test_introspect_endpoint.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # -*- coding: utf-8 -*-
  2. from json import loads
  3. from unittest.mock import MagicMock
  4. from oauthlib.common import urlencode
  5. from oauthlib.oauth2 import IntrospectEndpoint, RequestValidator
  6. from tests.unittest import TestCase
  7. class IntrospectEndpointTest(TestCase):
  8. def setUp(self):
  9. self.validator = MagicMock(wraps=RequestValidator())
  10. self.validator.client_authentication_required.return_value = True
  11. self.validator.authenticate_client.return_value = True
  12. self.validator.validate_bearer_token.return_value = True
  13. self.validator.introspect_token.return_value = {}
  14. self.endpoint = IntrospectEndpoint(self.validator)
  15. self.uri = 'should_not_matter'
  16. self.headers = {
  17. 'Content-Type': 'application/x-www-form-urlencoded',
  18. }
  19. self.resp_h = {
  20. 'Cache-Control': 'no-store',
  21. 'Content-Type': 'application/json',
  22. 'Pragma': 'no-cache'
  23. }
  24. self.resp_b = {
  25. "active": True
  26. }
  27. def test_introspect_token(self):
  28. for token_type in ('access_token', 'refresh_token', 'invalid'):
  29. body = urlencode([('token', 'foo'),
  30. ('token_type_hint', token_type)])
  31. h, b, s = self.endpoint.create_introspect_response(self.uri,
  32. headers=self.headers, body=body)
  33. self.assertEqual(h, self.resp_h)
  34. self.assertEqual(loads(b), self.resp_b)
  35. self.assertEqual(s, 200)
  36. def test_introspect_token_nohint(self):
  37. # don't specify token_type_hint
  38. body = urlencode([('token', 'foo')])
  39. h, b, s = self.endpoint.create_introspect_response(self.uri,
  40. headers=self.headers, body=body)
  41. self.assertEqual(h, self.resp_h)
  42. self.assertEqual(loads(b), self.resp_b)
  43. self.assertEqual(s, 200)
  44. def test_introspect_token_false(self):
  45. self.validator.introspect_token.return_value = None
  46. body = urlencode([('token', 'foo')])
  47. h, b, s = self.endpoint.create_introspect_response(self.uri,
  48. headers=self.headers, body=body)
  49. self.assertEqual(h, self.resp_h)
  50. self.assertEqual(loads(b), {"active": False})
  51. self.assertEqual(s, 200)
  52. def test_introspect_token_claims(self):
  53. self.validator.introspect_token.return_value = {"foo": "bar"}
  54. body = urlencode([('token', 'foo')])
  55. h, b, s = self.endpoint.create_introspect_response(self.uri,
  56. headers=self.headers, body=body)
  57. self.assertEqual(h, self.resp_h)
  58. self.assertEqual(loads(b), {"active": True, "foo": "bar"})
  59. self.assertEqual(s, 200)
  60. def test_introspect_token_claims_spoof_active(self):
  61. self.validator.introspect_token.return_value = {"foo": "bar", "active": False}
  62. body = urlencode([('token', 'foo')])
  63. h, b, s = self.endpoint.create_introspect_response(self.uri,
  64. headers=self.headers, body=body)
  65. self.assertEqual(h, self.resp_h)
  66. self.assertEqual(loads(b), {"active": True, "foo": "bar"})
  67. self.assertEqual(s, 200)
  68. def test_introspect_token_client_authentication_failed(self):
  69. self.validator.authenticate_client.return_value = False
  70. body = urlencode([('token', 'foo'),
  71. ('token_type_hint', 'access_token')])
  72. h, b, s = self.endpoint.create_introspect_response(self.uri,
  73. headers=self.headers, body=body)
  74. self.assertEqual(h, {
  75. 'Content-Type': 'application/json',
  76. 'Cache-Control': 'no-store',
  77. 'Pragma': 'no-cache',
  78. "WWW-Authenticate": 'Bearer error="invalid_client"'
  79. })
  80. self.assertEqual(loads(b)['error'], 'invalid_client')
  81. self.assertEqual(s, 401)
  82. def test_introspect_token_public_client_authentication(self):
  83. self.validator.client_authentication_required.return_value = False
  84. self.validator.authenticate_client_id.return_value = True
  85. for token_type in ('access_token', 'refresh_token', 'invalid'):
  86. body = urlencode([('token', 'foo'),
  87. ('token_type_hint', token_type)])
  88. h, b, s = self.endpoint.create_introspect_response(self.uri,
  89. headers=self.headers, body=body)
  90. self.assertEqual(h, self.resp_h)
  91. self.assertEqual(loads(b), self.resp_b)
  92. self.assertEqual(s, 200)
  93. def test_introspect_token_public_client_authentication_failed(self):
  94. self.validator.client_authentication_required.return_value = False
  95. self.validator.authenticate_client_id.return_value = False
  96. body = urlencode([('token', 'foo'),
  97. ('token_type_hint', 'access_token')])
  98. h, b, s = self.endpoint.create_introspect_response(self.uri,
  99. headers=self.headers, body=body)
  100. self.assertEqual(h, {
  101. 'Content-Type': 'application/json',
  102. 'Cache-Control': 'no-store',
  103. 'Pragma': 'no-cache',
  104. "WWW-Authenticate": 'Bearer error="invalid_client"'
  105. })
  106. self.assertEqual(loads(b)['error'], 'invalid_client')
  107. self.assertEqual(s, 401)
  108. def test_introspect_unsupported_token(self):
  109. endpoint = IntrospectEndpoint(self.validator,
  110. supported_token_types=['access_token'])
  111. body = urlencode([('token', 'foo'),
  112. ('token_type_hint', 'refresh_token')])
  113. h, b, s = endpoint.create_introspect_response(self.uri,
  114. headers=self.headers, body=body)
  115. self.assertEqual(h, self.resp_h)
  116. self.assertEqual(loads(b)['error'], 'unsupported_token_type')
  117. self.assertEqual(s, 400)
  118. h, b, s = endpoint.create_introspect_response(self.uri,
  119. headers=self.headers, body='')
  120. self.assertEqual(h, self.resp_h)
  121. self.assertEqual(loads(b)['error'], 'invalid_request')
  122. self.assertEqual(s, 400)
  123. def test_introspect_invalid_request_method(self):
  124. endpoint = IntrospectEndpoint(self.validator,
  125. supported_token_types=['access_token'])
  126. test_methods = ['GET', 'pUt', 'dEleTe', 'paTcH']
  127. test_methods = test_methods + [x.lower() for x in test_methods] + [x.upper() for x in test_methods]
  128. for method in test_methods:
  129. body = urlencode([('token', 'foo'),
  130. ('token_type_hint', 'refresh_token')])
  131. h, b, s = endpoint.create_introspect_response(self.uri,
  132. http_method = method, headers=self.headers, body=body)
  133. self.assertEqual(h, self.resp_h)
  134. self.assertEqual(loads(b)['error'], 'invalid_request')
  135. self.assertIn('Unsupported request method', loads(b)['error_description'])
  136. self.assertEqual(s, 400)
  137. def test_introspect_bad_post_request(self):
  138. endpoint = IntrospectEndpoint(self.validator,
  139. supported_token_types=['access_token'])
  140. for param in ['token', 'secret', 'code', 'foo']:
  141. uri = 'http://some.endpoint?' + urlencode([(param, 'secret')])
  142. body = urlencode([('token', 'foo'),
  143. ('token_type_hint', 'access_token')])
  144. h, b, s = endpoint.create_introspect_response(
  145. uri,
  146. headers=self.headers, body=body)
  147. self.assertEqual(h, self.resp_h)
  148. self.assertEqual(loads(b)['error'], 'invalid_request')
  149. self.assertIn('query parameters are not allowed', loads(b)['error_description'])
  150. self.assertEqual(s, 400)