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 client import FlowExchangeError 
 33  from client import OOB_CALLBACK_URN 
 34   
 35  try: 
 36    from urlparse import parse_qsl 
 37  except ImportError: 
 38    from cgi import parse_qsl 
 39   
 40   
 41  FLAGS = gflags.FLAGS 
 42   
 43  gflags.DEFINE_boolean('auth_local_webserver', True, 
 44                        ('Run a local web server to handle redirects during ' 
 45                         'OAuth authorization.')) 
 46   
 47  gflags.DEFINE_string('auth_host_name', 'localhost', 
 48                       ('Host name to use when running a local web server to ' 
 49                        'handle redirects during OAuth authorization.')) 
 50   
 51  gflags.DEFINE_multi_int('auth_host_port', [8080, 8090], 
 52                          ('Port to use when running a local web server to ' 
 53                           'handle redirects during OAuth authorization.')) 
 54   
 55   
56 -class ClientRedirectServer(BaseHTTPServer.HTTPServer):
57 """A server to handle OAuth 2.0 redirects back to localhost. 58 59 Waits for a single request and parses the query parameters 60 into query_params and then stops serving. 61 """ 62 query_params = {}
63 64
65 -class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
66 """A handler for OAuth 2.0 redirects back to localhost. 67 68 Waits for a single request and parses the query parameters 69 into the servers query_params and then stops serving. 70 """ 71
72 - def do_GET(s):
73 """Handle a GET request. 74 75 Parses the query parameters and prints a message 76 if the flow has completed. Note that we can't detect 77 if an error occurred. 78 """ 79 s.send_response(200) 80 s.send_header("Content-type", "text/html") 81 s.end_headers() 82 query = s.path.split('?', 1)[-1] 83 query = dict(parse_qsl(query)) 84 s.server.query_params = query 85 s.wfile.write("<html><head><title>Authentication Status</title></head>") 86 s.wfile.write("<body><p>The authentication flow has completed.</p>") 87 s.wfile.write("</body></html>")
88
89 - def log_message(self, format, *args):
90 """Do not log messages to stdout while running as command line program.""" 91 pass
92 93
94 -def run(flow, storage, http=None):
95 """Core code for a command-line application. 96 97 Args: 98 flow: Flow, an OAuth 2.0 Flow to step through. 99 storage: Storage, a Storage to store the credential in. 100 http: An instance of httplib2.Http.request 101 or something that acts like it. 102 103 Returns: 104 Credentials, the obtained credential. 105 """ 106 if FLAGS.auth_local_webserver: 107 success = False 108 port_number = 0 109 for port in FLAGS.auth_host_port: 110 port_number = port 111 try: 112 httpd = ClientRedirectServer((FLAGS.auth_host_name, port), 113 ClientRedirectHandler) 114 except socket.error, e: 115 pass 116 else: 117 success = True 118 break 119 FLAGS.auth_local_webserver = success 120 if not success: 121 print 'Failed to start a local webserver listening on either port 8080' 122 print 'or port 9090. Please check your firewall settings and locally' 123 print 'running programs that may be blocking or using those ports.' 124 print 125 print 'Falling back to --noauth_local_webserver and continuing with', 126 print 'authorization.' 127 print 128 129 if FLAGS.auth_local_webserver: 130 oauth_callback = 'http://%s:%s/' % (FLAGS.auth_host_name, port_number) 131 else: 132 oauth_callback = OOB_CALLBACK_URN 133 authorize_url = flow.step1_get_authorize_url(oauth_callback) 134 135 if FLAGS.auth_local_webserver: 136 webbrowser.open(authorize_url, new=1, autoraise=True) 137 print 'Your browser has been opened to visit:' 138 print 139 print ' ' + authorize_url 140 print 141 print 'If your browser is on a different machine then exit and re-run this' 142 print 'application with the command-line parameter ' 143 print 144 print ' --noauth_local_webserver' 145 print 146 else: 147 print 'Go to the following link in your browser:' 148 print 149 print ' ' + authorize_url 150 print 151 152 code = None 153 if FLAGS.auth_local_webserver: 154 httpd.handle_request() 155 if 'error' in httpd.query_params: 156 sys.exit('Authentication request was rejected.') 157 if 'code' in httpd.query_params: 158 code = httpd.query_params['code'] 159 else: 160 print 'Failed to find "code" in the query parameters of the redirect.' 161 sys.exit('Try running with --noauth_local_webserver.') 162 else: 163 code = raw_input('Enter verification code: ').strip() 164 165 try: 166 credential = flow.step2_exchange(code, http) 167 except FlowExchangeError, e: 168 sys.exit('Authentication has failed: %s' % e) 169 170 storage.put(credential) 171 credential.set_store(storage) 172 print 'Authentication successful.' 173 174 return credential
175