blob: d541eeb977912d7ff6cc1a6aeea9963d724ae1ca [file] [log] [blame]
Joe Gregorio695fdc12011-01-16 16:46:55 -05001# 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
17Do the OAuth 2.0 Web Server dance for
18a command line application. Stores the generated
19credentials in a common file that is used by
20other example apps in the same directory.
21"""
22
23__author__ = 'jcgregorio@google.com (Joe Gregorio)'
24__all__ = ["run"]
25
26import socket
27import sys
28import BaseHTTPServer
29import logging
30
31from optparse import OptionParser
32from oauth2client.file import Storage
33
34try:
35 from urlparse import parse_qsl
36except ImportError:
37 from cgi import parse_qsl
38
39# TODO(jcgregorio)
40# - docs
41# - error handling
Joe Gregorio695fdc12011-01-16 16:46:55 -050042
Joe Gregorio49e94d82011-01-28 16:36:13 -050043HOST_NAME = 'localhost'
44PORT_NUMBERS = [8080, 8090]
Joe Gregorio695fdc12011-01-16 16:46:55 -050045
46class ClientRedirectServer(BaseHTTPServer.HTTPServer):
47 """A server to handle OAuth 2.0 redirects back to localhost.
48
49 Waits for a single request and parses the query parameters
50 into query_params and then stops serving.
51 """
52 query_params = {}
53
54class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
55 """A handler for OAuth 2.0 redirects back to localhost.
56
57 Waits for a single request and parses the query parameters
58 into the servers query_params and then stops serving.
59 """
60
61 def do_GET(s):
62 """Handle a GET request
63
64 Checks the query parameters and if an error
65 occurred print a message of failure, otherwise
66 indicate success.
67 """
68 s.send_response(200)
69 s.send_header("Content-type", "text/html")
70 s.end_headers()
71 query = s.path.split('?', 1)[-1]
72 query = dict(parse_qsl(query))
73 s.server.query_params = query
74 s.wfile.write("<html><head><title>Authentication Status</title></head>")
75 if 'error' in query:
76 s.wfile.write("<body><p>The authentication request failed.</p>")
77 else:
78 s.wfile.write("<body><p>You have successfully authenticated</p>")
79 s.wfile.write("</body></html>")
80
81 def log_message(self, format, *args):
82 """Do not log messages to stdout while running as a command line program."""
83 pass
84
85def run(flow, filename):
86 """Core code for a command-line application.
87 """
88 parser = OptionParser()
89 parser.add_option("-f", "--file", dest="filename",
90 default=filename, help="write credentials to FILE", metavar="FILE")
Joe Gregorio49e94d82011-01-28 16:36:13 -050091
92 # The support for localhost is a work in progress and does not
93 # work at this point.
94 #parser.add_option("-p", "--no_local_web_server", dest="localhost",
95 # action="store_false",
96 # default=True,
97 # help="Do not run a web server on localhost to handle redirect URIs")
Joe Gregorio695fdc12011-01-16 16:46:55 -050098
99 (options, args) = parser.parse_args()
100
Joe Gregorio49e94d82011-01-28 16:36:13 -0500101#if options.localhost:
102# server_class = BaseHTTPServer.HTTPServer
103# try:
104# port_number = PORT_NUMBERS[0]
105# httpd = server_class((HOST_NAME, port_number), ClientRedirectHandler)
106# except socket.error:
107# port_number = PORT_NUMBERS[1]
108# try:
109# httpd = server_class((HOST_NAME, port_number), ClientRedirectHandler)
110# except socket.error:
111# options.localhost = False
112# redirect_uri = 'http://%s:%s/' % (HOST_NAME, port_number)
113#else:
114# redirect_uri = 'oob'
Joe Gregorio695fdc12011-01-16 16:46:55 -0500115
Joe Gregorio49e94d82011-01-28 16:36:13 -0500116 redirect_uri = 'oob'
117
118 authorize_url = flow.step1_get_authorize_url(redirect_uri)
Joe Gregorio695fdc12011-01-16 16:46:55 -0500119
120 print 'Go to the following link in your browser:'
121 print authorize_url
122 print
123
Joe Gregorio49e94d82011-01-28 16:36:13 -0500124#if options.localhost:
125# httpd.handle_request()
126# if 'error' in httpd.query_params:
127# sys.exit('Authentication request was rejected.')
128# if 'code' in httpd.query_params:
129# code = httpd.query_params['code']
130#else:
131 accepted = 'n'
132 while accepted.lower() == 'n':
133 accepted = raw_input('Have you authorized me? (y/n) ')
134 code = raw_input('What is the verification code? ').strip()
Joe Gregorio695fdc12011-01-16 16:46:55 -0500135
136 credentials = flow.step2_exchange(code)
137
138 Storage(options.filename).put(credentials)
139 print "You have successfully authenticated."