test_credentials_preservation.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. """Ensure credentials are preserved through the authorization.
  2. The Authorization Code Grant will need to preserve state as well as redirect
  3. uri and the Implicit Grant will need to preserve state.
  4. """
  5. import json
  6. from unittest import mock
  7. from oauthlib.oauth2 import (
  8. MobileApplicationServer, RequestValidator, WebApplicationServer,
  9. )
  10. from oauthlib.oauth2.rfc6749 import errors
  11. from tests.unittest import TestCase
  12. from .test_utils import get_fragment_credentials, get_query_credentials
  13. class PreservationTest(TestCase):
  14. DEFAULT_REDIRECT_URI = 'http://i.b./path'
  15. def setUp(self):
  16. self.validator = mock.MagicMock(spec=RequestValidator)
  17. self.validator.get_default_redirect_uri.return_value = self.DEFAULT_REDIRECT_URI
  18. self.validator.get_code_challenge.return_value = None
  19. self.validator.authenticate_client.side_effect = self.set_client
  20. self.web = WebApplicationServer(self.validator)
  21. self.mobile = MobileApplicationServer(self.validator)
  22. def set_client(self, request):
  23. request.client = mock.MagicMock()
  24. request.client.client_id = 'mocked'
  25. return True
  26. def test_state_preservation(self):
  27. auth_uri = 'http://example.com/path?state=xyz&client_id=abc&response_type='
  28. # authorization grant
  29. h, _, s = self.web.create_authorization_response(
  30. auth_uri + 'code', scopes=['random'])
  31. self.assertEqual(s, 302)
  32. self.assertIn('Location', h)
  33. self.assertEqual(get_query_credentials(h['Location'])['state'][0], 'xyz')
  34. # implicit grant
  35. h, _, s = self.mobile.create_authorization_response(
  36. auth_uri + 'token', scopes=['random'])
  37. self.assertEqual(s, 302)
  38. self.assertIn('Location', h)
  39. self.assertEqual(get_fragment_credentials(h['Location'])['state'][0], 'xyz')
  40. def test_redirect_uri_preservation(self):
  41. auth_uri = 'http://example.com/path?redirect_uri=http%3A%2F%2Fi.b%2Fpath&client_id=abc'
  42. redirect_uri = 'http://i.b/path'
  43. token_uri = 'http://example.com/path'
  44. # authorization grant
  45. h, _, s = self.web.create_authorization_response(
  46. auth_uri + '&response_type=code', scopes=['random'])
  47. self.assertEqual(s, 302)
  48. self.assertIn('Location', h)
  49. self.assertTrue(h['Location'].startswith(redirect_uri))
  50. # confirm_redirect_uri should return false if the redirect uri
  51. # was given in the authorization but not in the token request.
  52. self.validator.confirm_redirect_uri.return_value = False
  53. code = get_query_credentials(h['Location'])['code'][0]
  54. _, body, _ = self.web.create_token_response(token_uri,
  55. body='grant_type=authorization_code&code=%s' % code)
  56. self.assertEqual(json.loads(body)['error'], 'invalid_request')
  57. # implicit grant
  58. h, _, s = self.mobile.create_authorization_response(
  59. auth_uri + '&response_type=token', scopes=['random'])
  60. self.assertEqual(s, 302)
  61. self.assertIn('Location', h)
  62. self.assertTrue(h['Location'].startswith(redirect_uri))
  63. def test_invalid_redirect_uri(self):
  64. auth_uri = 'http://example.com/path?redirect_uri=http%3A%2F%2Fi.b%2Fpath&client_id=abc'
  65. self.validator.validate_redirect_uri.return_value = False
  66. # authorization grant
  67. self.assertRaises(errors.MismatchingRedirectURIError,
  68. self.web.create_authorization_response,
  69. auth_uri + '&response_type=code', scopes=['random'])
  70. # implicit grant
  71. self.assertRaises(errors.MismatchingRedirectURIError,
  72. self.mobile.create_authorization_response,
  73. auth_uri + '&response_type=token', scopes=['random'])
  74. def test_default_uri(self):
  75. auth_uri = 'http://example.com/path?state=xyz&client_id=abc'
  76. self.validator.get_default_redirect_uri.return_value = None
  77. # authorization grant
  78. self.assertRaises(errors.MissingRedirectURIError,
  79. self.web.create_authorization_response,
  80. auth_uri + '&response_type=code', scopes=['random'])
  81. # implicit grant
  82. self.assertRaises(errors.MissingRedirectURIError,
  83. self.mobile.create_authorization_response,
  84. auth_uri + '&response_type=token', scopes=['random'])
  85. def test_default_uri_in_token(self):
  86. auth_uri = 'http://example.com/path?state=xyz&client_id=abc'
  87. token_uri = 'http://example.com/path'
  88. # authorization grant
  89. h, _, s = self.web.create_authorization_response(
  90. auth_uri + '&response_type=code', scopes=['random'])
  91. self.assertEqual(s, 302)
  92. self.assertIn('Location', h)
  93. self.assertTrue(h['Location'].startswith(self.DEFAULT_REDIRECT_URI))
  94. # confirm_redirect_uri should return true if the redirect uri
  95. # was not given in the authorization AND not in the token request.
  96. self.validator.confirm_redirect_uri.return_value = True
  97. code = get_query_credentials(h['Location'])['code'][0]
  98. self.validator.validate_code.return_value = True
  99. _, body, s = self.web.create_token_response(token_uri,
  100. body='grant_type=authorization_code&code=%s' % code)
  101. self.assertEqual(s, 200)
  102. self.assertEqual(self.validator.confirm_redirect_uri.call_args[0][2], self.DEFAULT_REDIRECT_URI)