123 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # 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 'webrick'
 | |
| require 'launchy'
 | |
| 
 | |
| module Google
 | |
|   class APIClient
 | |
| 
 | |
|     # Small helper for the sample apps for performing OAuth 2.0 flows from the command
 | |
|     # line or in any other installed app environment.
 | |
|     #
 | |
|     # @example
 | |
|     #
 | |
|     #    client = Google::APIClient.new
 | |
|     #    flow = Google::APIClient::InstalledAppFlow.new(
 | |
|     #      :client_id => '691380668085.apps.googleusercontent.com',
 | |
|     #      :client_secret => '...,
 | |
|     #      :scope => 'https://www.googleapis.com/auth/drive'
 | |
|     #    )
 | |
|     #    client.authorization = flow.authorize
 | |
|     #
 | |
|     class InstalledAppFlow
 | |
|       
 | |
|       RESPONSE_BODY = <<-HTML
 | |
|         <html>
 | |
|           <head>
 | |
|             <script>
 | |
|               function closeWindow() { 
 | |
|                 window.open('', '_self', '');
 | |
|                 window.close();
 | |
|               }
 | |
|               setTimeout(closeWindow, 10);
 | |
|             </script>
 | |
|           </head>
 | |
|           <body>You may close this window.</body>
 | |
|         </html>
 | |
|       HTML
 | |
|       
 | |
|       ##
 | |
|       # Configure the flow
 | |
|       #
 | |
|       # @param [Hash] options The configuration parameters for the client.
 | |
|       # @option options [Fixnum] :port
 | |
|       #   Port to run the embedded server on. Defaults to 9292
 | |
|       # @option options [String] :client_id 
 | |
|       #   A unique identifier issued to the client to identify itself to the
 | |
|       #   authorization server.
 | |
|       # @option options [String] :client_secret
 | |
|       #   A shared symmetric secret issued by the authorization server,
 | |
|       #   which is used to authenticate the client.
 | |
|       # @option options [String] :scope
 | |
|       #   The scope of the access request, expressed either as an Array
 | |
|       #   or as a space-delimited String.
 | |
|       #
 | |
|       # @see Signet::OAuth2::Client
 | |
|       def initialize(options)
 | |
|         @port = options[:port] || 9292
 | |
|         @authorization = Signet::OAuth2::Client.new({
 | |
|           :authorization_uri => 'https://accounts.google.com/o/oauth2/auth',
 | |
|           :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
 | |
|           :redirect_uri => "http://localhost:#{@port}/"}.update(options)
 | |
|         )
 | |
|       end
 | |
|       
 | |
|       ##
 | |
|       # Request authorization. Opens a browser and waits for response.
 | |
|       #
 | |
|       # @param [Google::APIClient::FileStorage] storage
 | |
|       #  Optional object that responds to :write_credentials, used to serialize
 | |
|       #  the OAuth 2 credentials after completing the flow.
 | |
|       #
 | |
|       # @return [Signet::OAuth2::Client]
 | |
|       #  Authorization instance, nil if user cancelled.
 | |
|       def authorize(storage=nil)
 | |
|         auth = @authorization
 | |
|     
 | |
|         server = WEBrick::HTTPServer.new(
 | |
|           :Port => @port,
 | |
|           :BindAddress =>"localhost",
 | |
|           :Logger => WEBrick::Log.new(STDOUT, 0),
 | |
|           :AccessLog => []
 | |
|         )
 | |
|         trap("INT") { server.shutdown }
 | |
|         
 | |
|         server.mount_proc '/' do |req, res|
 | |
|             auth.code = req.query['code']
 | |
|             if auth.code
 | |
|               auth.fetch_access_token!
 | |
|             end
 | |
|             res.status = WEBrick::HTTPStatus::RC_ACCEPTED
 | |
|             res.body = RESPONSE_BODY
 | |
|             server.stop
 | |
|         end
 | |
| 
 | |
|         Launchy.open(auth.authorization_uri.to_s)
 | |
|         server.start
 | |
|         if @authorization.access_token
 | |
|           if storage.respond_to?(:write_credentials)
 | |
|             storage.write_credentials(@authorization)
 | |
|           end
 | |
|           return @authorization
 | |
|         else
 | |
|           return nil
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|   end
 | |
| end
 | |
| 
 |