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 The run() function is called from your application and runs through all the 100 steps to obtain credentials. It takes a Flow argument and attempts to open an 101 authorization server page in the user's default web browser. The server asks 102 the user to grant your application access to the user's data. If the user 103 grants access, the run() function returns new credentials. The new credentials 104 are also stored in the Storage argument, which updates the file associated 105 with the Storage object. 106 107 It presumes it is run from a command-line application and supports the 108 following flags: 109 110 --auth_host_name: Host name to use when running a local web server 111 to handle redirects during OAuth authorization. 112 (default: 'localhost') 113 114 --auth_host_port: Port to use when running a local web server to handle 115 redirects during OAuth authorization.; 116 repeat this option to specify a list of values 117 (default: '[8080, 8090]') 118 (an integer) 119 120 --[no]auth_local_webserver: Run a local web server to handle redirects 121 during OAuth authorization. 122 (default: 'true') 123 124 Since it uses flags make sure to initialize the gflags module before calling 125 run(). 126 127 Args: 128 flow: Flow, an OAuth 2.0 Flow to step through. 129 storage: Storage, a Storage to store the credential in. 130 http: An instance of httplib2.Http.request 131 or something that acts like it. 132 133 Returns: 134 Credentials, the obtained credential. 135 """ 136 if FLAGS.auth_local_webserver: 137 success = False 138 port_number = 0 139 for port in FLAGS.auth_host_port: 140 port_number = port 141 try: 142 httpd = ClientRedirectServer((FLAGS.auth_host_name, port), 143 ClientRedirectHandler) 144 except socket.error, e: 145 pass 146 else: 147 success = True 148 break 149 FLAGS.auth_local_webserver = success 150 if not success: 151 print 'Failed to start a local webserver listening on either port 8080' 152 print 'or port 9090. Please check your firewall settings and locally' 153 print 'running programs that may be blocking or using those ports.' 154 print 155 print 'Falling back to --noauth_local_webserver and continuing with', 156 print 'authorization.' 157 print 158 159 if FLAGS.auth_local_webserver: 160 oauth_callback = 'http://%s:%s/' % (FLAGS.auth_host_name, port_number) 161 else: 162 oauth_callback = OOB_CALLBACK_URN 163 flow.redirect_uri = oauth_callback 164 authorize_url = flow.step1_get_authorize_url() 165 166 if FLAGS.auth_local_webserver: 167 webbrowser.open(authorize_url, new=1, autoraise=True) 168 print 'Your browser has been opened to visit:' 169 print 170 print ' ' + authorize_url 171 print 172 print 'If your browser is on a different machine then exit and re-run this' 173 print 'application with the command-line parameter ' 174 print 175 print ' --noauth_local_webserver' 176 print 177 else: 178 print 'Go to the following link in your browser:' 179 print 180 print ' ' + authorize_url 181 print 182 183 code = None 184 if FLAGS.auth_local_webserver: 185 httpd.handle_request() 186 if 'error' in httpd.query_params: 187 sys.exit('Authentication request was rejected.') 188 if 'code' in httpd.query_params: 189 code = httpd.query_params['code'] 190 else: 191 print 'Failed to find "code" in the query parameters of the redirect.' 192 sys.exit('Try running with --noauth_local_webserver.') 193 else: 194 code = raw_input('Enter verification code: ').strip() 195 196 try: 197 credential = flow.step2_exchange(code, http=http) 198 except FlowExchangeError, e: 199 sys.exit('Authentication has failed: %s' % e) 200 201 storage.put(credential) 202 credential.set_store(storage) 203 print 'Authentication successful.' 204 205 return credential
206