Package oauth2client :: Module tools
[hide private]
[frames] | no frames]

Source Code for Module oauth2client.tools

  1  # Copyright (C) 2010 Google Inc. 
  2  # 
  3  # Licensed under the Apache License, Version 2.0 (the "License"); 
  4  # you may not use this file except in compliance with the License. 
  5  # You may obtain a copy of the License at 
  6  # 
  7  #      http://www.apache.org/licenses/LICENSE-2.0 
  8  # 
  9  # Unless required by applicable law or agreed to in writing, software 
 10  # distributed under the License is distributed on an "AS IS" BASIS, 
 11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 12  # See the License for the specific language governing permissions and 
 13  # limitations under the License. 
 14   
 15  """Command-line tools for authenticating via OAuth 2.0 
 16   
 17  Do the OAuth 2.0 Web Server dance for a command line application. Stores the 
 18  generated credentials in a common file that is used by other example apps in 
 19  the same directory. 
 20  """ 
 21   
 22  __author__ = 'jcgregorio@google.com (Joe Gregorio)' 
 23  __all__ = ['run'] 
 24   
 25   
 26  import BaseHTTPServer 
 27  import gflags 
 28  import socket 
 29  import sys 
 30  import webbrowser 
 31   
 32  from oauth2client.client import FlowExchangeError 
 33  from oauth2client.client import OOB_CALLBACK_URN 
 34  from oauth2client import util 
 35   
 36  try: 
 37    from urlparse import parse_qsl 
 38  except ImportError: 
 39    from cgi import parse_qsl 
 40   
 41   
 42  FLAGS = gflags.FLAGS 
 43   
 44  gflags.DEFINE_boolean('auth_local_webserver', True, 
 45                        ('Run a local web server to handle redirects during ' 
 46                         'OAuth authorization.')) 
 47   
 48  gflags.DEFINE_string('auth_host_name', 'localhost', 
 49                       ('Host name to use when running a local web server to ' 
 50                        'handle redirects during OAuth authorization.')) 
 51   
 52  gflags.DEFINE_multi_int('auth_host_port', [8080, 8090], 
 53                          ('Port to use when running a local web server to ' 
 54                           'handle redirects during OAuth authorization.')) 
55 56 57 -class ClientRedirectServer(BaseHTTPServer.HTTPServer):
58 """A server to handle OAuth 2.0 redirects back to localhost. 59 60 Waits for a single request and parses the query parameters 61 into query_params and then stops serving. 62 """ 63 query_params = {}
64
65 66 -class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
67 """A handler for OAuth 2.0 redirects back to localhost. 68 69 Waits for a single request and parses the query parameters 70 into the servers query_params and then stops serving. 71 """ 72
73 - def do_GET(s):
74 """Handle a GET request. 75 76 Parses the query parameters and prints a message 77 if the flow has completed. Note that we can't detect 78 if an error occurred. 79 """ 80 s.send_response(200) 81 s.send_header("Content-type", "text/html") 82 s.end_headers() 83 query = s.path.split('?', 1)[-1] 84 query = dict(parse_qsl(query)) 85 s.server.query_params = query 86 s.wfile.write("<html><head><title>Authentication Status</title></head>") 87 s.wfile.write("<body><p>The authentication flow has completed.</p>") 88 s.wfile.write("</body></html>")
89
90 - def log_message(self, format, *args):
91 """Do not log messages to stdout while running as command line program.""" 92 pass
93
94 95 @util.positional(2) 96 -def run(flow, storage, http=None):
97 """Core code for a command-line application. 98 99 Args: 100 flow: Flow, an OAuth 2.0 Flow to step through. 101 storage: Storage, a Storage to store the credential in. 102 http: An instance of httplib2.Http.request 103 or something that acts like it. 104 105 Returns: 106 Credentials, the obtained credential. 107 """ 108 if FLAGS.auth_local_webserver: 109 success = False 110 port_number = 0 111 for port in FLAGS.auth_host_port: 112 port_number = port 113 try: 114 httpd = ClientRedirectServer((FLAGS.auth_host_name, port), 115 ClientRedirectHandler) 116 except socket.error, e: 117 pass 118 else: 119 success = True 120 break 121 FLAGS.auth_local_webserver = success 122 if not success: 123 print 'Failed to start a local webserver listening on either port 8080' 124 print 'or port 9090. Please check your firewall settings and locally' 125 print 'running programs that may be blocking or using those ports.' 126 print 127 print 'Falling back to --noauth_local_webserver and continuing with', 128 print 'authorization.' 129 print 130 131 if FLAGS.auth_local_webserver: 132 oauth_callback = 'http://%s:%s/' % (FLAGS.auth_host_name, port_number) 133 else: 134 oauth_callback = OOB_CALLBACK_URN 135 flow.redirect_uri = oauth_callback 136 authorize_url = flow.step1_get_authorize_url() 137 138 if FLAGS.auth_local_webserver: 139 webbrowser.open(authorize_url, new=1, autoraise=True) 140 print 'Your browser has been opened to visit:' 141 print 142 print ' ' + authorize_url 143 print 144 print 'If your browser is on a different machine then exit and re-run this' 145 print 'application with the command-line parameter ' 146 print 147 print ' --noauth_local_webserver' 148 print 149 else: 150 print 'Go to the following link in your browser:' 151 print 152 print ' ' + authorize_url 153 print 154 155 code = None 156 if FLAGS.auth_local_webserver: 157 httpd.handle_request() 158 if 'error' in httpd.query_params: 159 sys.exit('Authentication request was rejected.') 160 if 'code' in httpd.query_params: 161 code = httpd.query_params['code'] 162 else: 163 print 'Failed to find "code" in the query parameters of the redirect.' 164 sys.exit('Try running with --noauth_local_webserver.') 165 else: 166 code = raw_input('Enter verification code: ').strip() 167 168 try: 169 credential = flow.step2_exchange(code, http=http) 170 except FlowExchangeError, e: 171 sys.exit('Authentication has failed: %s' % e) 172 173 storage.put(credential) 174 credential.set_store(storage) 175 print 'Authentication successful.' 176 177 return credential
178