/gdata/sample_util.py

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