revocation.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # -*- coding: utf-8 -*-
  2. """
  3. oauthlib.oauth2.rfc6749.endpoint.revocation
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. An implementation of the OAuth 2 `Token Revocation`_ spec (draft 11).
  6. .. _`Token Revocation`: http://tools.ietf.org/html/draft-ietf-oauth-revocation-11
  7. """
  8. from __future__ import absolute_import, unicode_literals
  9. import logging
  10. from oauthlib.common import Request
  11. from .base import BaseEndpoint, catch_errors_and_unavailability
  12. from ..errors import InvalidClientError, UnsupportedTokenTypeError
  13. from ..errors import InvalidRequestError, OAuth2Error
  14. log = logging.getLogger(__name__)
  15. class RevocationEndpoint(BaseEndpoint):
  16. """Token revocation endpoint.
  17. Endpoint used by authenticated clients to revoke access and refresh tokens.
  18. Commonly this will be part of the Authorization Endpoint.
  19. """
  20. valid_token_types = ('access_token', 'refresh_token')
  21. def __init__(self, request_validator, supported_token_types=None,
  22. enable_jsonp=False):
  23. BaseEndpoint.__init__(self)
  24. self.request_validator = request_validator
  25. self.supported_token_types = (
  26. supported_token_types or self.valid_token_types)
  27. self.enable_jsonp = enable_jsonp
  28. @catch_errors_and_unavailability
  29. def create_revocation_response(self, uri, http_method='POST', body=None,
  30. headers=None):
  31. """Revoke supplied access or refresh token.
  32. The authorization server responds with HTTP status code 200 if the
  33. token has been revoked sucessfully or if the client submitted an
  34. invalid token.
  35. Note: invalid tokens do not cause an error response since the client
  36. cannot handle such an error in a reasonable way. Moreover, the purpose
  37. of the revocation request, invalidating the particular token, is
  38. already achieved.
  39. The content of the response body is ignored by the client as all
  40. necessary information is conveyed in the response code.
  41. An invalid token type hint value is ignored by the authorization server
  42. and does not influence the revocation response.
  43. """
  44. request = Request(
  45. uri, http_method=http_method, body=body, headers=headers)
  46. try:
  47. self.validate_revocation_request(request)
  48. log.debug('Token revocation valid for %r.', request)
  49. except OAuth2Error as e:
  50. log.debug('Client error during validation of %r. %r.', request, e)
  51. response_body = e.json
  52. if self.enable_jsonp and request.callback:
  53. response_body = '%s(%s);' % (request.callback, response_body)
  54. return {}, response_body, e.status_code
  55. self.request_validator.revoke_token(request.token,
  56. request.token_type_hint, request)
  57. response_body = ''
  58. if self.enable_jsonp and request.callback:
  59. response_body = request.callback + '();'
  60. return {}, response_body, 200
  61. def validate_revocation_request(self, request):
  62. """Ensure the request is valid.
  63. The client constructs the request by including the following parameters
  64. using the "application/x-www-form-urlencoded" format in the HTTP
  65. request entity-body:
  66. token (REQUIRED). The token that the client wants to get revoked.
  67. token_type_hint (OPTIONAL). A hint about the type of the token
  68. submitted for revocation. Clients MAY pass this parameter in order to
  69. help the authorization server to optimize the token lookup. If the
  70. server is unable to locate the token using the given hint, it MUST
  71. extend its search accross all of its supported token types. An
  72. authorization server MAY ignore this parameter, particularly if it is
  73. able to detect the token type automatically. This specification
  74. defines two such values:
  75. * access_token: An Access Token as defined in [RFC6749],
  76. `section 1.4`_
  77. * refresh_token: A Refresh Token as defined in [RFC6749],
  78. `section 1.5`_
  79. Specific implementations, profiles, and extensions of this
  80. specification MAY define other values for this parameter using
  81. the registry defined in `Section 4.1.2`_.
  82. The client also includes its authentication credentials as described in
  83. `Section 2.3`_. of [`RFC6749`_].
  84. .. _`section 1.4`: http://tools.ietf.org/html/rfc6749#section-1.4
  85. .. _`section 1.5`: http://tools.ietf.org/html/rfc6749#section-1.5
  86. .. _`section 2.3`: http://tools.ietf.org/html/rfc6749#section-2.3
  87. .. _`Section 4.1.2`: http://tools.ietf.org/html/draft-ietf-oauth-revocation-11#section-4.1.2
  88. .. _`RFC6749`: http://tools.ietf.org/html/rfc6749
  89. """
  90. if not request.token:
  91. raise InvalidRequestError(request=request,
  92. description='Missing token parameter.')
  93. if self.request_validator.client_authentication_required(request):
  94. if not self.request_validator.authenticate_client(request):
  95. raise InvalidClientError(request=request)
  96. if (request.token_type_hint and
  97. request.token_type_hint in self.valid_token_types and
  98. request.token_type_hint not in self.supported_token_types):
  99. raise UnsupportedTokenTypeError(request=request)