PageRenderTime 68ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/test_auth.py

https://github.com/askedrelic/libgreader
Python | 228 lines | 186 code | 17 blank | 25 comment | 3 complexity | f232da5ac25782274e00aca328c96ef3 MD5 | raw file
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. libG(oogle)Reader
  5. Copyright (C) 2010 Matt Behrens <askedrelic@gmail.com> http://asktherelic.com
  6. Python library for working with the unofficial Google Reader API.
  7. Unit tests for oauth and ClientAuthMethod in libgreader.
  8. """
  9. try:
  10. import unittest2 as unittest
  11. except:
  12. import unittest
  13. from libgreader import GoogleReader, OAuthMethod, OAuth2Method, ClientAuthMethod, Feed
  14. import requests
  15. import re
  16. from .config import *
  17. class TestClientAuthMethod(unittest.TestCase):
  18. def test_ClientAuthMethod_login(self):
  19. ca = ClientAuthMethod(username,password)
  20. self.assertNotEqual(ca, None)
  21. def test_reader(self):
  22. ca = ClientAuthMethod(username,password)
  23. reader = GoogleReader(ca)
  24. self.assertNotEqual(reader, None)
  25. def test_bad_user_details(self):
  26. self.assertRaises(IOError, ClientAuthMethod, 'asdsa', '')
  27. def test_reader_user_info(self):
  28. ca = ClientAuthMethod(username,password)
  29. reader = GoogleReader(ca)
  30. info = reader.getUserInfo()
  31. self.assertEqual(dict, type(info))
  32. self.assertEqual(firstname, info['userName'])
  33. #automated approval of oauth url
  34. #returns mechanize Response of the last "You have accepted" page
  35. def automated_oauth_approval(url):
  36. #general process is:
  37. # 1. assume user isn't logged in, so get redirected to google accounts
  38. # login page. login using test account credentials
  39. # 2. redirected back to oauth approval page. br.submit() should choose the
  40. # first submit on that page, which is the "Accept" button
  41. br = mechanize.Browser()
  42. br.open(url)
  43. br.select_form(nr=0)
  44. br["Email"] = username
  45. br["Passwd"] = password
  46. response1 = br.submit()
  47. br.select_form(nr=0)
  48. req2 = br.click(type="submit", nr=0)
  49. response2 = br.open(req2)
  50. return response2
  51. @unittest.skip('deprecated')
  52. class TestOAuth(unittest.TestCase):
  53. def test_oauth_login(self):
  54. auth = OAuthMethod(oauth_key, oauth_secret)
  55. self.assertNotEqual(auth, None)
  56. def test_getting_request_token(self):
  57. auth = OAuthMethod(oauth_key, oauth_secret)
  58. token, token_secret = auth.setAndGetRequestToken()
  59. url = auth.buildAuthUrl()
  60. response = automated_oauth_approval(url)
  61. self.assertNotEqual(-1,response.get_data().find('You have successfully granted'))
  62. def test_full_auth_process_without_callback(self):
  63. auth = OAuthMethod(oauth_key, oauth_secret)
  64. auth.setRequestToken()
  65. auth_url = auth.buildAuthUrl()
  66. response = automated_oauth_approval(auth_url)
  67. auth.setAccessToken()
  68. reader = GoogleReader(auth)
  69. info = reader.getUserInfo()
  70. self.assertEqual(dict, type(info))
  71. self.assertEqual(firstname, info['userName'])
  72. def test_full_auth_process_with_callback(self):
  73. auth = OAuthMethod(oauth_key, oauth_secret)
  74. #must be a working callback url for testing
  75. auth.setCallback("http://www.asktherelic.com")
  76. token, token_secret = auth.setAndGetRequestToken()
  77. auth_url = auth.buildAuthUrl()
  78. #callback section
  79. #get response, which is a redirect to the callback url
  80. response = automated_oauth_approval(auth_url)
  81. query_string = urlparse.urlparse(response.geturl()).query
  82. #grab the verifier token from the callback url query string
  83. token_verifier = urlparse.parse_qs(query_string)['oauth_verifier'][0]
  84. auth.setAccessTokenFromCallback(token, token_secret, token_verifier)
  85. reader = GoogleReader(auth)
  86. info = reader.getUserInfo()
  87. self.assertEqual(dict, type(info))
  88. self.assertEqual(firstname, info['userName'])
  89. #automate getting the approval token
  90. def mechanize_oauth2_approval(url):
  91. """
  92. general process is:
  93. 1. assume user isn't logged in, so get redirected to google accounts
  94. login page. login using account credentials
  95. But, if the user has already granted access, the user is auto redirected without
  96. having to confirm again.
  97. 2. redirected back to oauth approval page. br.submit() should choose the
  98. first submit on that page, which is the "Accept" button
  99. 3. mechanize follows the redirect, and should throw 40X exception and
  100. we return the token
  101. """
  102. br = mechanize.Browser()
  103. br.open(url)
  104. br.select_form(nr=0)
  105. br["Email"] = username
  106. br["Passwd"] = password
  107. try:
  108. response1 = br.submit()
  109. br.select_form(nr=0)
  110. response2 = br.submit()
  111. except Exception as e:
  112. #watch for 40X exception on trying to load redirect page
  113. pass
  114. callback_url = br.geturl()
  115. # split off the token in hackish fashion
  116. return callback_url.split('code=')[1]
  117. def automated_oauth2_approval(url):
  118. """
  119. general process is:
  120. 1. assume user isn't logged in, so get redirected to google accounts
  121. login page. login using account credentials
  122. 2. get redirected to oauth approval screen
  123. 3. authorize oauth app
  124. """
  125. auth_url = url
  126. headers = {'Referer': auth_url}
  127. s = requests.Session()
  128. r1 = s.get(auth_url)
  129. post_data = dict((x[0],x[1]) for x in re.findall('name="(.*?)".*?value="(.*?)"', str(r1.content), re.MULTILINE))
  130. post_data['Email'] = username
  131. post_data['Passwd'] = password
  132. post_data['timeStmp'] = ''
  133. post_data['secTok'] = ''
  134. post_data['signIn'] = 'Sign in'
  135. post_data['GALX'] = s.cookies['GALX']
  136. r2 = s.post('https://accounts.google.com/ServiceLoginAuth', data=post_data, headers=headers, allow_redirects=False)
  137. #requests is fucking up the url encoding and double encoding ampersands
  138. scope_url = r2.headers['location'].replace('amp%3B','')
  139. # now get auth screen
  140. r3 = s.get(scope_url)
  141. # unless we have already authed!
  142. if 'asktherelic' in r3.url:
  143. code = r3.url.split('=')[1]
  144. return code
  145. post_data = dict((x[0],x[1]) for x in re.findall('name="(.*?)".*?value="(.*?)"', str(r3.content)))
  146. post_data['submit_access'] = 'true'
  147. post_data['_utf8'] = '&#9731'
  148. # again, fucked encoding for amp;
  149. action_url = re.findall('action="(.*?)"', str(r3.content))[0].replace('amp;','')
  150. r4 = s.post(action_url, data=post_data, headers=headers, allow_redirects=False)
  151. code = r4.headers['Location'].split('=')[1]
  152. s.close()
  153. return code
  154. @unittest.skipIf("client_id" not in globals(), 'OAuth2 config not setup')
  155. class TestOAuth2(unittest.TestCase):
  156. def test_full_auth_and_access_userdata(self):
  157. auth = OAuth2Method(client_id, client_secret)
  158. auth.setRedirectUri(redirect_url)
  159. url = auth.buildAuthUrl()
  160. token = automated_oauth2_approval(url)
  161. auth.code = token
  162. auth.setAccessToken()
  163. reader = GoogleReader(auth)
  164. info = reader.getUserInfo()
  165. self.assertEqual(dict, type(info))
  166. self.assertEqual(firstname, info['userName'])
  167. def test_oauth_subscribe(self):
  168. auth = OAuth2Method(client_id, client_secret)
  169. auth.setRedirectUri(redirect_url)
  170. url = auth.buildAuthUrl()
  171. token = automated_oauth2_approval(url)
  172. auth.code = token
  173. auth.setAccessToken()
  174. auth.setActionToken()
  175. reader = GoogleReader(auth)
  176. slashdot = 'feed/http://rss.slashdot.org/Slashdot/slashdot'
  177. #unsubscribe always return true; revert feedlist state
  178. self.assertTrue(reader.unsubscribe(slashdot))
  179. # now subscribe
  180. self.assertTrue(reader.subscribe(slashdot))
  181. # wait for server to update
  182. import time
  183. time.sleep(1)
  184. reader.buildSubscriptionList()
  185. # test subscribe successful
  186. self.assertIn(slashdot, [x.id for x in reader.getSubscriptionList()])
  187. if __name__ == '__main__':
  188. unittest.main()