PageRenderTime 37ms CodeModel.GetById 1ms app.highlight 29ms RepoModel.GetById 2ms app.codeStats 0ms

/gdata/sample_util.py

http://radioappz.googlecode.com/
Python | 269 lines | 218 code | 27 blank | 24 comment | 25 complexity | 5a2120ee54c469167281306c404c4aa0 MD5 | raw file
  1#!/usr/bin/env python
  2#
  3# Copyright (C) 2009 Google Inc.
  4#
  5# Licensed under the Apache License, Version 2.0 (the "License");
  6# you may not use this file except in compliance with the License.
  7# You may obtain a copy of the License at
  8#
  9#      http://www.apache.org/licenses/LICENSE-2.0
 10#
 11# Unless required by applicable law or agreed to in writing, software
 12# distributed under the License is distributed on an "AS IS" BASIS,
 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14# See the License for the specific language governing permissions and
 15# limitations under the License.
 16
 17
 18"""Provides utility functions used with command line samples."""
 19
 20# This module is used for version 2 of the Google Data APIs.
 21
 22import sys
 23import getpass
 24import urllib
 25import gdata.gauth
 26
 27__author__ = 'j.s@google.com (Jeff Scudder)'
 28
 29
 30CLIENT_LOGIN = 1
 31AUTHSUB = 2
 32OAUTH = 3
 33
 34HMAC = 1
 35RSA = 2
 36
 37
 38class SettingsUtil(object):
 39  """Gather's user preferences from flags or command prompts.
 40
 41  An instance of this object stores the choices made by the user. At some
 42  point it might be useful to save the user's preferences so that they do
 43  not need to always set flags or answer preference prompts.
 44  """
 45
 46  def __init__(self, prefs=None):
 47    self.prefs = prefs or {}
 48
 49  def get_param(self, name, prompt='', secret=False, ask=True, reuse=False):
 50    # First, check in this objects stored preferences.
 51    if name in self.prefs:
 52     return self.prefs[name]
 53    # Second, check for a command line parameter.
 54    value = None
 55    for i in xrange(len(sys.argv)):
 56      if sys.argv[i].startswith('--%s=' % name):
 57        value = sys.argv[i].split('=')[1]
 58      elif sys.argv[i] == '--%s' % name:
 59        value = sys.argv[i + 1]
 60    # Third, if it was not on the command line, ask the user to input the
 61    # value.
 62    if value is None and ask:
 63      prompt = '%s: ' % prompt
 64      if secret:
 65        value = getpass.getpass(prompt)
 66      else:
 67        value = raw_input(prompt)
 68    # If we want to save the preference for reuse in future requests, add it
 69    # to this object's prefs.
 70    if value is not None and reuse:
 71      self.prefs[name] = value
 72    return value
 73
 74  def authorize_client(self, client, auth_type=None, service=None,
 75                       source=None, scopes=None, oauth_type=None,
 76                       consumer_key=None, consumer_secret=None):
 77    """Uses command line arguments, or prompts user for token values."""
 78    if 'client_auth_token' in self.prefs:
 79      return
 80    if auth_type is None:
 81      auth_type = int(self.get_param(
 82          'auth_type', 'Please choose the authorization mechanism you want'
 83          ' to use.\n'
 84          '1. to use your email address and password (ClientLogin)\n'
 85          '2. to use a web browser to visit an auth web page (AuthSub)\n'
 86          '3. if you have registed to use OAuth\n', reuse=True))
 87
 88    # Get the scopes for the services we want to access.
 89    if auth_type == AUTHSUB or auth_type == OAUTH:
 90      if scopes is None:
 91        scopes = self.get_param(
 92            'scopes', 'Enter the URL prefixes (scopes) for the resources you '
 93            'would like to access.\nFor multiple scope URLs, place a comma '
 94            'between each URL.\n'
 95            'Example: http://www.google.com/calendar/feeds/,'
 96            'http://www.google.com/m8/feeds/\n', reuse=True).split(',')
 97      elif isinstance(scopes, (str, unicode)):
 98        scopes = scopes.split(',')
 99
100    if auth_type == CLIENT_LOGIN:
101      email = self.get_param('email', 'Please enter your username',
102                             reuse=False)
103      password = self.get_param('password', 'Password', True, reuse=False)
104      if service is None:
105        service = self.get_param(
106            'service', 'What is the name of the service you wish to access?'
107            '\n(See list:'
108            ' http://code.google.com/apis/gdata/faq.html#clientlogin)',
109            reuse=True)
110      if source is None:
111        source = self.get_param('source', ask=False, reuse=True)
112      client.client_login(email, password, source=source, service=service)
113    elif auth_type == AUTHSUB:
114      auth_sub_token = self.get_param('auth_sub_token', ask=False, reuse=True)
115      session_token = self.get_param('session_token', ask=False, reuse=True)
116      private_key = None
117      auth_url = None
118      single_use_token = None
119      rsa_private_key = self.get_param(
120          'rsa_private_key',
121          'If you want to use secure mode AuthSub, please provide the\n'
122          ' location of your RSA private key which corresponds to the\n'
123          ' certificate you have uploaded for your domain. If you do not\n'
124          ' have an RSA key, simply press enter', reuse=True)
125
126      if rsa_private_key:
127        try:
128          private_key_file = open(rsa_private_key, 'rb')
129          private_key = private_key_file.read()
130          private_key_file.close()
131        except IOError:
132          print 'Unable to read private key from file'
133
134      if private_key is not None:
135        if client.auth_token is None:
136          if session_token:
137            client.auth_token = gdata.gauth.SecureAuthSubToken(
138                session_token, private_key, scopes)
139            self.prefs['client_auth_token'] = gdata.gauth.token_to_blob(
140                client.auth_token)
141            return
142          elif auth_sub_token:
143            client.auth_token = gdata.gauth.SecureAuthSubToken(
144                auth_sub_token, private_key, scopes)
145            client.upgrade_token()
146            self.prefs['client_auth_token'] = gdata.gauth.token_to_blob(
147                client.auth_token)
148            return
149
150        auth_url = gdata.gauth.generate_auth_sub_url(
151            'http://gauthmachine.appspot.com/authsub', scopes, True)
152        print 'with a private key, get ready for this URL', auth_url
153
154      else:
155        if client.auth_token is None:
156          if session_token:
157            client.auth_token = gdata.gauth.AuthSubToken(session_token,
158                                                         scopes)
159            self.prefs['client_auth_token'] = gdata.gauth.token_to_blob(
160                client.auth_token)
161            return
162          elif auth_sub_token:
163            client.auth_token = gdata.gauth.AuthSubToken(auth_sub_token,
164                                                         scopes)
165            client.upgrade_token()
166            self.prefs['client_auth_token'] = gdata.gauth.token_to_blob(
167                client.auth_token)
168            return
169
170          auth_url = gdata.gauth.generate_auth_sub_url(
171              'http://gauthmachine.appspot.com/authsub', scopes)
172
173      print 'Visit the following URL in your browser to authorize this app:'
174      print str(auth_url)
175      print 'After agreeing to authorize the app, copy the token value from'
176      print ' the URL. Example: "www.google.com/?token=ab12" token value is'
177      print ' ab12'
178      token_value = raw_input('Please enter the token value: ')
179      if private_key is not None:
180        single_use_token = gdata.gauth.SecureAuthSubToken(
181            token_value, private_key, scopes)
182      else:
183        single_use_token = gdata.gauth.AuthSubToken(token_value, scopes)
184      client.auth_token = single_use_token
185      client.upgrade_token()
186
187    elif auth_type == OAUTH:
188      if oauth_type is None:
189        oauth_type = int(self.get_param(
190            'oauth_type', 'Please choose the authorization mechanism you want'
191            ' to use.\n'
192            '1. use an HMAC signature using your consumer key and secret\n'
193            '2. use RSA with your private key to sign requests\n',
194            reuse=True))
195
196      consumer_key = self.get_param(
197          'consumer_key', 'Please enter your OAuth conumer key '
198          'which identifies your app', reuse=True)
199
200      if oauth_type == HMAC:
201        consumer_secret = self.get_param(
202            'consumer_secret', 'Please enter your OAuth conumer secret '
203            'which you share with the OAuth provider', True, reuse=False)
204        # Swap out this code once the client supports requesting an oauth
205        # token.
206        # Get a request token.
207        request_token = client.get_oauth_token(
208            scopes, 'http://gauthmachine.appspot.com/oauth', consumer_key,
209            consumer_secret=consumer_secret)
210      elif oauth_type == RSA:
211        rsa_private_key = self.get_param(
212            'rsa_private_key',
213            'Please provide the location of your RSA private key which\n'
214            ' corresponds to the certificate you have uploaded for your'
215            ' domain.',
216            reuse=True)
217        try:
218          private_key_file = open(rsa_private_key, 'rb')
219          private_key = private_key_file.read()
220          private_key_file.close()
221        except IOError:
222          print 'Unable to read private key from file'
223
224        request_token = client.get_oauth_token(
225            scopes, 'http://gauthmachine.appspot.com/oauth', consumer_key,
226            rsa_private_key=private_key)
227      else:
228        print 'Invalid OAuth signature type'
229        return None
230
231      # Authorize the request token in the browser.
232      print 'Visit the following URL in your browser to authorize this app:'
233      print str(request_token.generate_authorization_url())
234      print 'After agreeing to authorize the app, copy URL from the browser\'s'
235      print ' address bar.'
236      url = raw_input('Please enter the url: ')
237      gdata.gauth.authorize_request_token(request_token, url)
238      # Exchange for an access token.
239      client.auth_token = client.get_access_token(request_token)
240    else:
241      print 'Invalid authorization type.'
242      return None
243    if client.auth_token:
244      self.prefs['client_auth_token'] = gdata.gauth.token_to_blob(
245          client.auth_token)
246
247
248def get_param(name, prompt='', secret=False, ask=True):
249  settings = SettingsUtil()
250  return settings.get_param(name=name, prompt=prompt, secret=secret, ask=ask)
251
252
253def authorize_client(client, auth_type=None, service=None, source=None,
254                     scopes=None, oauth_type=None, consumer_key=None,
255                     consumer_secret=None):
256  """Uses command line arguments, or prompts user for token values."""
257  settings = SettingsUtil()
258  return settings.authorize_client(client=client, auth_type=auth_type,
259                                   service=service, source=source,
260                                   scopes=scopes, oauth_type=oauth_type,
261                                   consumer_key=consumer_key,
262                                   consumer_secret=consumer_secret)
263
264
265def print_options():
266  """Displays usage information, available command line params."""
267  # TODO: fill in the usage description for authorizing the client.
268  print ''
269