# 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 You may close this window. 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. # # @return [Signet::OAuth2::Client] # Authorization instance, nil if user cancelled. def authorize 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 return @authorization else return nil end end end end end