summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Huot <JonathanHuot@users.noreply.github.com>2018-12-20 15:47:01 +0100
committerGitHub <noreply@github.com>2018-12-20 15:47:01 +0100
commit650f5dbc750c5c07882b15bd99852c7a3000759e (patch)
tree74afb6e035f064ffe142bb97381936eb187dc77b
parentcbb13792261b2df5c5ff408f9e73cdcb99aa94dd (diff)
parent3893b1764af522970e143f422967338eecbb9c1e (diff)
downloadoauthlib-650f5dbc750c5c07882b15bd99852c7a3000759e.tar.gz
Merge pull request #634 from oauthlib/dry-up-code
Extract common code into helpers
-rw-r--r--oauthlib/oauth2/rfc6749/endpoints/base.py25
-rw-r--r--oauthlib/oauth2/rfc6749/endpoints/introspect.py22
-rw-r--r--oauthlib/oauth2/rfc6749/endpoints/revocation.py22
-rw-r--r--oauthlib/oauth2/rfc6749/grant_types/authorization_code.py29
-rw-r--r--oauthlib/oauth2/rfc6749/grant_types/base.py91
-rw-r--r--oauthlib/oauth2/rfc6749/grant_types/client_credentials.py6
-rw-r--r--oauthlib/oauth2/rfc6749/grant_types/implicit.py25
-rw-r--r--oauthlib/oauth2/rfc6749/grant_types/refresh_token.py6
-rw-r--r--oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py6
9 files changed, 104 insertions, 128 deletions
diff --git a/oauthlib/oauth2/rfc6749/endpoints/base.py b/oauthlib/oauth2/rfc6749/endpoints/base.py
index cdb015f..c0fc726 100644
--- a/oauthlib/oauth2/rfc6749/endpoints/base.py
+++ b/oauthlib/oauth2/rfc6749/endpoints/base.py
@@ -12,7 +12,8 @@ import functools
import logging
from ..errors import (FatalClientError, OAuth2Error, ServerError,
- TemporarilyUnavailableError)
+ TemporarilyUnavailableError, InvalidRequestError,
+ InvalidClientError, UnsupportedTokenTypeError)
log = logging.getLogger(__name__)
@@ -39,6 +40,28 @@ class BaseEndpoint(object):
def catch_errors(self, catch_errors):
self._catch_errors = catch_errors
+ def _raise_on_missing_token(self, request):
+ """Raise error on missing token."""
+ if not request.token:
+ raise InvalidRequestError(request=request,
+ description='Missing token parameter.')
+ def _raise_on_invalid_client(self, request):
+ """Raise on failed client authentication."""
+ if self.request_validator.client_authentication_required(request):
+ if not self.request_validator.authenticate_client(request):
+ log.debug('Client authentication failed, %r.', request)
+ raise InvalidClientError(request=request)
+ elif not self.request_validator.authenticate_client_id(request.client_id, request):
+ log.debug('Client authentication failed, %r.', request)
+ raise InvalidClientError(request=request)
+
+ def _raise_on_unsupported_token(self, request):
+ """Raise on unsupported tokens."""
+ if (request.token_type_hint and
+ request.token_type_hint in self.valid_token_types and
+ request.token_type_hint not in self.supported_token_types):
+ raise UnsupportedTokenTypeError(request=request)
+
def catch_errors_and_unavailability(f):
@functools.wraps(f)
diff --git a/oauthlib/oauth2/rfc6749/endpoints/introspect.py b/oauthlib/oauth2/rfc6749/endpoints/introspect.py
index 4a531e4..ff7a32d 100644
--- a/oauthlib/oauth2/rfc6749/endpoints/introspect.py
+++ b/oauthlib/oauth2/rfc6749/endpoints/introspect.py
@@ -14,8 +14,7 @@ import logging
from oauthlib.common import Request
-from ..errors import (InvalidClientError, InvalidRequestError, OAuth2Error,
- UnsupportedTokenTypeError)
+from ..errors import OAuth2Error, UnsupportedTokenTypeError
from .base import BaseEndpoint, catch_errors_and_unavailability
log = logging.getLogger(__name__)
@@ -118,19 +117,6 @@ class IntrospectEndpoint(BaseEndpoint):
.. _`section 1.5`: http://tools.ietf.org/html/rfc6749#section-1.5
.. _`RFC6749`: http://tools.ietf.org/html/rfc6749
"""
- if not request.token:
- raise InvalidRequestError(request=request,
- description='Missing token parameter.')
-
- if self.request_validator.client_authentication_required(request):
- if not self.request_validator.authenticate_client(request):
- log.debug('Client authentication failed, %r.', request)
- raise InvalidClientError(request=request)
- elif not self.request_validator.authenticate_client_id(request.client_id, request):
- log.debug('Client authentication failed, %r.', request)
- raise InvalidClientError(request=request)
-
- if (request.token_type_hint and
- request.token_type_hint in self.valid_token_types and
- request.token_type_hint not in self.supported_token_types):
- raise UnsupportedTokenTypeError(request=request)
+ self._raise_on_missing_token(request)
+ self._raise_on_invalid_client(request)
+ self._raise_on_unsupported_token(request)
diff --git a/oauthlib/oauth2/rfc6749/endpoints/revocation.py b/oauthlib/oauth2/rfc6749/endpoints/revocation.py
index f7e591d..4cd96a7 100644
--- a/oauthlib/oauth2/rfc6749/endpoints/revocation.py
+++ b/oauthlib/oauth2/rfc6749/endpoints/revocation.py
@@ -13,8 +13,7 @@ import logging
from oauthlib.common import Request
-from ..errors import (InvalidClientError, InvalidRequestError, OAuth2Error,
- UnsupportedTokenTypeError)
+from ..errors import OAuth2Error, UnsupportedTokenTypeError
from .base import BaseEndpoint, catch_errors_and_unavailability
log = logging.getLogger(__name__)
@@ -122,19 +121,6 @@ class RevocationEndpoint(BaseEndpoint):
.. _`Section 4.1.2`: https://tools.ietf.org/html/draft-ietf-oauth-revocation-11#section-4.1.2
.. _`RFC6749`: https://tools.ietf.org/html/rfc6749
"""
- if not request.token:
- raise InvalidRequestError(request=request,
- description='Missing token parameter.')
-
- if self.request_validator.client_authentication_required(request):
- if not self.request_validator.authenticate_client(request):
- log.debug('Client authentication failed, %r.', request)
- raise InvalidClientError(request=request)
- elif not self.request_validator.authenticate_client_id(request.client_id, request):
- log.debug('Client authentication failed, %r.', request)
- raise InvalidClientError(request=request)
-
- if (request.token_type_hint and
- request.token_type_hint in self.valid_token_types and
- request.token_type_hint not in self.supported_token_types):
- raise UnsupportedTokenTypeError(request=request)
+ self._raise_on_missing_token(request)
+ self._raise_on_invalid_client(request)
+ self._raise_on_unsupported_token(request)
diff --git a/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py b/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
index d56330a..6463391 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
@@ -11,7 +11,6 @@ import json
import logging
from oauthlib import common
-from oauthlib.uri_validate import is_absolute_uri
from .. import errors
from .base import GrantTypeBase
@@ -164,7 +163,7 @@ class AuthorizationCodeGrant(GrantTypeBase):
def create_authorization_code(self, request):
"""
Generates an authorization grant represented as a dictionary.
-
+
:param request: OAuthlib request.
:type request: oauthlib.common.Request
"""
@@ -297,11 +296,7 @@ class AuthorizationCodeGrant(GrantTypeBase):
oauthlib.oauth2.BearerToken.
"""
- headers = {
- 'Content-Type': 'application/json',
- 'Cache-Control': 'no-store',
- 'Pragma': 'no-cache',
- }
+ headers = self._get_default_headers()
try:
self.validate_token_request(request)
log.debug('Token request validation ok for %r.', request)
@@ -364,24 +359,10 @@ class AuthorizationCodeGrant(GrantTypeBase):
# https://tools.ietf.org/html/rfc6749#section-3.1.2
log.debug('Validating redirection uri %s for client %s.',
request.redirect_uri, request.client_id)
- if request.redirect_uri is not None:
- request.using_default_redirect_uri = False
- log.debug('Using provided redirect_uri %s', request.redirect_uri)
- if not is_absolute_uri(request.redirect_uri):
- raise errors.InvalidRedirectURIError(request=request)
- if not self.request_validator.validate_redirect_uri(
- request.client_id, request.redirect_uri, request):
- raise errors.MismatchingRedirectURIError(request=request)
- else:
- request.redirect_uri = self.request_validator.get_default_redirect_uri(
- request.client_id, request)
- request.using_default_redirect_uri = True
- log.debug('Using default redirect_uri %s.', request.redirect_uri)
- if not request.redirect_uri:
- raise errors.MissingRedirectURIError(request=request)
- if not is_absolute_uri(request.redirect_uri):
- raise errors.InvalidRedirectURIError(request=request)
+ # OPTIONAL. As described in Section 3.1.2.
+ # https://tools.ietf.org/html/rfc6749#section-3.1.2
+ self._handle_redirects(request)
# Then check for normal errors.
diff --git a/oauthlib/oauth2/rfc6749/grant_types/base.py b/oauthlib/oauth2/rfc6749/grant_types/base.py
index 43f9db4..f0772e2 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/base.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/base.py
@@ -9,51 +9,53 @@ import logging
from itertools import chain
from oauthlib.common import add_params_to_uri
+from oauthlib.uri_validate import is_absolute_uri
from oauthlib.oauth2.rfc6749 import errors, utils
from ..request_validator import RequestValidator
log = logging.getLogger(__name__)
+
class ValidatorsContainer(object):
"""
- Container object for holding custom validator callables to be invoked
- as part of the grant type `validate_authorization_request()` or
- `validate_authorization_request()` methods on the various grant types.
+ Container object for holding custom validator callables to be invoked
+ as part of the grant type `validate_authorization_request()` or
+ `validate_authorization_request()` methods on the various grant types.
- Authorization validators must be callables that take a request object and
- return a dict, which may contain items to be added to the `request_info`
- returned from the grant_type after validation.
+ Authorization validators must be callables that take a request object and
+ return a dict, which may contain items to be added to the `request_info`
+ returned from the grant_type after validation.
- Token validators must be callables that take a request object and
- return None.
+ Token validators must be callables that take a request object and
+ return None.
- Both authorization validators and token validators may raise OAuth2
- exceptions if validation conditions fail.
+ Both authorization validators and token validators may raise OAuth2
+ exceptions if validation conditions fail.
- Authorization validators added to `pre_auth` will be run BEFORE
- the standard validations (but after the critical ones that raise
- fatal errors) as part of `validate_authorization_request()`
+ Authorization validators added to `pre_auth` will be run BEFORE
+ the standard validations (but after the critical ones that raise
+ fatal errors) as part of `validate_authorization_request()`
- Authorization validators added to `post_auth` will be run AFTER
- the standard validations as part of `validate_authorization_request()`
+ Authorization validators added to `post_auth` will be run AFTER
+ the standard validations as part of `validate_authorization_request()`
- Token validators added to `pre_token` will be run BEFORE
- the standard validations as part of `validate_token_request()`
+ Token validators added to `pre_token` will be run BEFORE
+ the standard validations as part of `validate_token_request()`
- Token validators added to `post_token` will be run AFTER
- the standard validations as part of `validate_token_request()`
+ Token validators added to `post_token` will be run AFTER
+ the standard validations as part of `validate_token_request()`
- For example:
+ For example:
- >>> def my_auth_validator(request):
- ... return {'myval': True}
- >>> auth_code_grant = AuthorizationCodeGrant(request_validator)
- >>> auth_code_grant.custom_validators.pre_auth.append(my_auth_validator)
- >>> def my_token_validator(request):
- ... if not request.everything_okay:
- ... raise errors.OAuth2Error("uh-oh")
- >>> auth_code_grant.custom_validators.post_token.append(my_token_validator)
+ >>> def my_auth_validator(request):
+ ... return {'myval': True}
+ >>> auth_code_grant = AuthorizationCodeGrant(request_validator)
+ >>> auth_code_grant.custom_validators.pre_auth.append(my_auth_validator)
+ >>> def my_token_validator(request):
+ ... if not request.everything_okay:
+ ... raise errors.OAuth2Error("uh-oh")
+ >>> auth_code_grant.custom_validators.post_token.append(my_token_validator)
"""
def __init__(self, post_auth, post_token,
@@ -216,3 +218,36 @@ class GrantTypeBase(object):
raise NotImplementedError(
'Subclasses must set a valid default_response_mode')
+
+ def _get_default_headers(self):
+ """Create default headers for grant responses."""
+ return {
+ 'Content-Type': 'application/json',
+ 'Cache-Control': 'no-store',
+ 'Pragma': 'no-cache',
+ }
+
+ def _handle_redirects(self, request):
+ if request.redirect_uri is not None:
+ request.using_default_redirect_uri = False
+ log.debug('Using provided redirect_uri %s', request.redirect_uri)
+ if not is_absolute_uri(request.redirect_uri):
+ raise errors.InvalidRedirectURIError(request=request)
+
+ # The authorization server MUST verify that the redirection URI
+ # to which it will redirect the access token matches a
+ # redirection URI registered by the client as described in
+ # Section 3.1.2.
+ # https://tools.ietf.org/html/rfc6749#section-3.1.2
+ if not self.request_validator.validate_redirect_uri(
+ request.client_id, request.redirect_uri, request):
+ raise errors.MismatchingRedirectURIError(request=request)
+ else:
+ request.redirect_uri = self.request_validator.get_default_redirect_uri(
+ request.client_id, request)
+ request.using_default_redirect_uri = True
+ log.debug('Using default redirect_uri %s.', request.redirect_uri)
+ if not request.redirect_uri:
+ raise errors.MissingRedirectURIError(request=request)
+ if not is_absolute_uri(request.redirect_uri):
+ raise errors.InvalidRedirectURIError(request=request)
diff --git a/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py b/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py
index 0e4f545..c966795 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py
@@ -67,11 +67,7 @@ class ClientCredentialsGrant(GrantTypeBase):
.. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1
.. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2
"""
- headers = {
- 'Content-Type': 'application/json',
- 'Cache-Control': 'no-store',
- 'Pragma': 'no-cache',
- }
+ headers = self._get_default_headers()
try:
log.debug('Validating access token request, %r.', request)
self.validate_token_request(request)
diff --git a/oauthlib/oauth2/rfc6749/grant_types/implicit.py b/oauthlib/oauth2/rfc6749/grant_types/implicit.py
index b29953b..d6de906 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/implicit.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/implicit.py
@@ -8,7 +8,6 @@ from __future__ import absolute_import, unicode_literals
import logging
from oauthlib import common
-from oauthlib.uri_validate import is_absolute_uri
from .. import errors
from .base import GrantTypeBase
@@ -307,29 +306,7 @@ class ImplicitGrant(GrantTypeBase):
# OPTIONAL. As described in Section 3.1.2.
# https://tools.ietf.org/html/rfc6749#section-3.1.2
- if request.redirect_uri is not None:
- request.using_default_redirect_uri = False
- log.debug('Using provided redirect_uri %s', request.redirect_uri)
- if not is_absolute_uri(request.redirect_uri):
- raise errors.InvalidRedirectURIError(request=request)
-
- # The authorization server MUST verify that the redirection URI
- # to which it will redirect the access token matches a
- # redirection URI registered by the client as described in
- # Section 3.1.2.
- # https://tools.ietf.org/html/rfc6749#section-3.1.2
- if not self.request_validator.validate_redirect_uri(
- request.client_id, request.redirect_uri, request):
- raise errors.MismatchingRedirectURIError(request=request)
- else:
- request.redirect_uri = self.request_validator.get_default_redirect_uri(
- request.client_id, request)
- request.using_default_redirect_uri = True
- log.debug('Using default redirect_uri %s.', request.redirect_uri)
- if not request.redirect_uri:
- raise errors.MissingRedirectURIError(request=request)
- if not is_absolute_uri(request.redirect_uri):
- raise errors.InvalidRedirectURIError(request=request)
+ self._handle_redirects(request)
# Then check for normal errors.
diff --git a/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py b/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py
index 67d65a7..bd519e8 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py
@@ -54,11 +54,7 @@ class RefreshTokenGrant(GrantTypeBase):
.. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1
.. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2
"""
- headers = {
- 'Content-Type': 'application/json',
- 'Cache-Control': 'no-store',
- 'Pragma': 'no-cache',
- }
+ headers = self._get_default_headers()
try:
log.debug('Validating refresh token request, %r.', request)
self.validate_token_request(request)
diff --git a/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py b/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py
index cb5a4ca..f765d91 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py
@@ -87,11 +87,7 @@ class ResourceOwnerPasswordCredentialsGrant(GrantTypeBase):
.. _`Section 5.1`: https://tools.ietf.org/html/rfc6749#section-5.1
.. _`Section 5.2`: https://tools.ietf.org/html/rfc6749#section-5.2
"""
- headers = {
- 'Content-Type': 'application/json',
- 'Cache-Control': 'no-store',
- 'Pragma': 'no-cache',
- }
+ headers = self._get_default_headers()
try:
if self.request_validator.client_authentication_required(request):
log.debug('Authenticating client, %r.', request)