mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Update oauthlib-3.1.1
This commit is contained in:
parent
e58aa40099
commit
d76838a607
64 changed files with 4329 additions and 1421 deletions
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
oauthlib.oauth1
|
||||
~~~~~~~~~~~~~~
|
||||
|
@ -6,14 +5,24 @@ oauthlib.oauth1
|
|||
This module is a wrapper for the most recent implementation of OAuth 1.0 Client
|
||||
and Server classes.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from .rfc5849 import Client
|
||||
from .rfc5849 import SIGNATURE_HMAC, SIGNATURE_RSA, SIGNATURE_PLAINTEXT
|
||||
from .rfc5849 import (SIGNATURE_HMAC,
|
||||
SIGNATURE_HMAC_SHA1,
|
||||
SIGNATURE_HMAC_SHA256,
|
||||
SIGNATURE_HMAC_SHA512,
|
||||
SIGNATURE_RSA,
|
||||
SIGNATURE_RSA_SHA1,
|
||||
SIGNATURE_RSA_SHA256,
|
||||
SIGNATURE_RSA_SHA512,
|
||||
SIGNATURE_PLAINTEXT)
|
||||
from .rfc5849 import SIGNATURE_TYPE_AUTH_HEADER, SIGNATURE_TYPE_QUERY
|
||||
from .rfc5849 import SIGNATURE_TYPE_BODY
|
||||
from .rfc5849.request_validator import RequestValidator
|
||||
from .rfc5849.endpoints import RequestTokenEndpoint, AuthorizationEndpoint
|
||||
from .rfc5849.endpoints import AccessTokenEndpoint, ResourceEndpoint
|
||||
from .rfc5849.endpoints import SignatureOnlyEndpoint, WebApplicationServer
|
||||
from .rfc5849.errors import *
|
||||
from .rfc5849.errors import (InsecureTransportError,
|
||||
InvalidClientError,
|
||||
InvalidRequestError,
|
||||
InvalidSignatureMethodError,
|
||||
OAuth1Error)
|
||||
|
|
|
@ -1,36 +1,68 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
oauthlib.oauth1.rfc5849
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This module is an implementation of various logic needed
|
||||
for signing and checking OAuth 1.0 RFC 5849 requests.
|
||||
|
||||
It supports all three standard signature methods defined in RFC 5849:
|
||||
|
||||
- HMAC-SHA1
|
||||
- RSA-SHA1
|
||||
- PLAINTEXT
|
||||
|
||||
It also supports signature methods that are not defined in RFC 5849. These are
|
||||
based on the standard ones but replace SHA-1 with the more secure SHA-256:
|
||||
|
||||
- HMAC-SHA256
|
||||
- RSA-SHA256
|
||||
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
import base64
|
||||
import hashlib
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
import urllib.parse as urlparse
|
||||
|
||||
import sys
|
||||
try:
|
||||
import urlparse
|
||||
except ImportError:
|
||||
import urllib.parse as urlparse
|
||||
from oauthlib.common import (
|
||||
Request, generate_nonce, generate_timestamp, to_unicode, urlencode,
|
||||
)
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
bytes_type = bytes
|
||||
else:
|
||||
bytes_type = str
|
||||
|
||||
from oauthlib.common import Request, urlencode, generate_nonce
|
||||
from oauthlib.common import generate_timestamp, to_unicode
|
||||
from . import parameters, signature
|
||||
|
||||
SIGNATURE_HMAC = "HMAC-SHA1"
|
||||
SIGNATURE_RSA = "RSA-SHA1"
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Available signature methods
|
||||
#
|
||||
# Note: SIGNATURE_HMAC and SIGNATURE_RSA are kept for backward compatibility
|
||||
# with previous versions of this library, when it the only HMAC-based and
|
||||
# RSA-based signature methods were HMAC-SHA1 and RSA-SHA1. But now that it
|
||||
# supports other hashing algorithms besides SHA1, explicitly identifying which
|
||||
# hashing algorithm is being used is recommended.
|
||||
#
|
||||
# Note: if additional values are defined here, don't forget to update the
|
||||
# imports in "../__init__.py" so they are available outside this module.
|
||||
|
||||
SIGNATURE_HMAC_SHA1 = "HMAC-SHA1"
|
||||
SIGNATURE_HMAC_SHA256 = "HMAC-SHA256"
|
||||
SIGNATURE_HMAC_SHA512 = "HMAC-SHA512"
|
||||
SIGNATURE_HMAC = SIGNATURE_HMAC_SHA1 # deprecated variable for HMAC-SHA1
|
||||
|
||||
SIGNATURE_RSA_SHA1 = "RSA-SHA1"
|
||||
SIGNATURE_RSA_SHA256 = "RSA-SHA256"
|
||||
SIGNATURE_RSA_SHA512 = "RSA-SHA512"
|
||||
SIGNATURE_RSA = SIGNATURE_RSA_SHA1 # deprecated variable for RSA-SHA1
|
||||
|
||||
SIGNATURE_PLAINTEXT = "PLAINTEXT"
|
||||
SIGNATURE_METHODS = (SIGNATURE_HMAC, SIGNATURE_RSA, SIGNATURE_PLAINTEXT)
|
||||
|
||||
SIGNATURE_METHODS = (
|
||||
SIGNATURE_HMAC_SHA1,
|
||||
SIGNATURE_HMAC_SHA256,
|
||||
SIGNATURE_HMAC_SHA512,
|
||||
SIGNATURE_RSA_SHA1,
|
||||
SIGNATURE_RSA_SHA256,
|
||||
SIGNATURE_RSA_SHA512,
|
||||
SIGNATURE_PLAINTEXT
|
||||
)
|
||||
|
||||
SIGNATURE_TYPE_AUTH_HEADER = 'AUTH_HEADER'
|
||||
SIGNATURE_TYPE_QUERY = 'QUERY'
|
||||
|
@ -39,12 +71,16 @@ SIGNATURE_TYPE_BODY = 'BODY'
|
|||
CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'
|
||||
|
||||
|
||||
class Client(object):
|
||||
class Client:
|
||||
|
||||
"""A client used to sign OAuth 1.0 RFC 5849 requests."""
|
||||
SIGNATURE_METHODS = {
|
||||
SIGNATURE_HMAC: signature.sign_hmac_sha1_with_client,
|
||||
SIGNATURE_RSA: signature.sign_rsa_sha1_with_client,
|
||||
SIGNATURE_HMAC_SHA1: signature.sign_hmac_sha1_with_client,
|
||||
SIGNATURE_HMAC_SHA256: signature.sign_hmac_sha256_with_client,
|
||||
SIGNATURE_HMAC_SHA512: signature.sign_hmac_sha512_with_client,
|
||||
SIGNATURE_RSA_SHA1: signature.sign_rsa_sha1_with_client,
|
||||
SIGNATURE_RSA_SHA256: signature.sign_rsa_sha256_with_client,
|
||||
SIGNATURE_RSA_SHA512: signature.sign_rsa_sha512_with_client,
|
||||
SIGNATURE_PLAINTEXT: signature.sign_plaintext_with_client
|
||||
}
|
||||
|
||||
|
@ -57,7 +93,7 @@ class Client(object):
|
|||
resource_owner_key=None,
|
||||
resource_owner_secret=None,
|
||||
callback_uri=None,
|
||||
signature_method=SIGNATURE_HMAC,
|
||||
signature_method=SIGNATURE_HMAC_SHA1,
|
||||
signature_type=SIGNATURE_TYPE_AUTH_HEADER,
|
||||
rsa_key=None, verifier=None, realm=None,
|
||||
encoding='utf-8', decoding=None,
|
||||
|
@ -105,10 +141,11 @@ class Client(object):
|
|||
def __repr__(self):
|
||||
attrs = vars(self).copy()
|
||||
attrs['client_secret'] = '****' if attrs['client_secret'] else None
|
||||
attrs['rsa_key'] = '****' if attrs['rsa_key'] else None
|
||||
attrs[
|
||||
'resource_owner_secret'] = '****' if attrs['resource_owner_secret'] else None
|
||||
attribute_str = ', '.join('%s=%s' % (k, v) for k, v in attrs.items())
|
||||
return '<%s %s>' % (self.__class__.__name__, attribute_str)
|
||||
attribute_str = ', '.join('{}={}'.format(k, v) for k, v in attrs.items())
|
||||
return '<{} {}>'.format(self.__class__.__name__, attribute_str)
|
||||
|
||||
def get_oauth_signature(self, request):
|
||||
"""Get an OAuth signature to be used in signing a request
|
||||
|
@ -118,7 +155,7 @@ class Client(object):
|
|||
replace any netloc part of the request argument's uri attribute
|
||||
value.
|
||||
|
||||
.. _`section 3.4.1.2`: http://tools.ietf.org/html/rfc5849#section-3.4.1.2
|
||||
.. _`section 3.4.1.2`: https://tools.ietf.org/html/rfc5849#section-3.4.1.2
|
||||
"""
|
||||
if self.signature_method == SIGNATURE_PLAINTEXT:
|
||||
# fast-path
|
||||
|
@ -131,25 +168,24 @@ class Client(object):
|
|||
uri_query=urlparse.urlparse(uri).query,
|
||||
body=body,
|
||||
headers=headers)
|
||||
log.debug("Collected params: {0}".format(collected_params))
|
||||
log.debug("Collected params: {}".format(collected_params))
|
||||
|
||||
normalized_params = signature.normalize_parameters(collected_params)
|
||||
normalized_uri = signature.normalize_base_string_uri(uri,
|
||||
headers.get('Host', None))
|
||||
log.debug("Normalized params: {0}".format(normalized_params))
|
||||
log.debug("Normalized URI: {0}".format(normalized_uri))
|
||||
normalized_uri = signature.base_string_uri(uri, headers.get('Host', None))
|
||||
log.debug("Normalized params: {}".format(normalized_params))
|
||||
log.debug("Normalized URI: {}".format(normalized_uri))
|
||||
|
||||
base_string = signature.construct_base_string(request.http_method,
|
||||
base_string = signature.signature_base_string(request.http_method,
|
||||
normalized_uri, normalized_params)
|
||||
|
||||
log.debug("Base signing string: {0}".format(base_string))
|
||||
log.debug("Signing: signature base string: {}".format(base_string))
|
||||
|
||||
if self.signature_method not in self.SIGNATURE_METHODS:
|
||||
raise ValueError('Invalid signature method.')
|
||||
|
||||
sig = self.SIGNATURE_METHODS[self.signature_method](base_string, self)
|
||||
|
||||
log.debug("Signature: {0}".format(sig))
|
||||
log.debug("Signature: {}".format(sig))
|
||||
return sig
|
||||
|
||||
def get_oauth_params(self, request):
|
||||
|
@ -174,10 +210,12 @@ class Client(object):
|
|||
params.append(('oauth_verifier', self.verifier))
|
||||
|
||||
# providing body hash for requests other than x-www-form-urlencoded
|
||||
# as described in http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html
|
||||
# as described in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-4.1.1
|
||||
# 4.1.1. When to include the body hash
|
||||
# * [...] MUST NOT include an oauth_body_hash parameter on requests with form-encoded request bodies
|
||||
# * [...] SHOULD include the oauth_body_hash parameter on all other requests.
|
||||
# Note that SHA-1 is vulnerable. The spec acknowledges that in https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00#section-6.2
|
||||
# At this time, no further effort has been made to replace SHA-1 for the OAuth Request Body Hash extension.
|
||||
content_type = request.headers.get('Content-Type', None)
|
||||
content_type_eligible = content_type and content_type.find('application/x-www-form-urlencoded') < 0
|
||||
if request.body is not None and content_type_eligible:
|
||||
|
@ -278,8 +316,8 @@ class Client(object):
|
|||
# header field set to "application/x-www-form-urlencoded".
|
||||
elif not should_have_params and has_params:
|
||||
raise ValueError(
|
||||
"Body contains parameters but Content-Type header was {0} "
|
||||
"instead of {1}".format(content_type or "not set",
|
||||
"Body contains parameters but Content-Type header was {} "
|
||||
"instead of {}".format(content_type or "not set",
|
||||
CONTENT_TYPE_FORM_URLENCODED))
|
||||
|
||||
# 3.5.2. Form-Encoded Body
|
||||
|
@ -296,7 +334,7 @@ class Client(object):
|
|||
raise ValueError(
|
||||
'Body signatures may only be used with form-urlencoded content')
|
||||
|
||||
# We amend http://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
|
||||
# We amend https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
|
||||
# with the clause that parameters from body should only be included
|
||||
# in non GET or HEAD requests. Extracting the request body parameters
|
||||
# and including them in the signature base string would give semantic
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from .access_token import AccessTokenEndpoint
|
||||
from .authorization import AuthorizationEndpoint
|
||||
from .base import BaseEndpoint
|
||||
from .request_token import RequestTokenEndpoint
|
||||
from .authorization import AuthorizationEndpoint
|
||||
from .access_token import AccessTokenEndpoint
|
||||
from .resource import ResourceEndpoint
|
||||
from .signature_only import SignatureOnlyEndpoint
|
||||
from .pre_configured import WebApplicationServer
|
||||
|
||||
from .pre_configured import WebApplicationServer # isort:skip
|
||||
|
|
|
@ -8,14 +8,12 @@ OAuth 1.0 RFC 5849. It validates the correctness of access token requests,
|
|||
creates and persists tokens as well as create the proper response to be
|
||||
returned to the client.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from oauthlib.common import urlencode
|
||||
|
||||
from .base import BaseEndpoint
|
||||
from .. import errors
|
||||
from .base import BaseEndpoint
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -37,7 +35,8 @@ class AccessTokenEndpoint(BaseEndpoint):
|
|||
Similar to OAuth 2, indication of granted scopes will be included as a
|
||||
space separated list in ``oauth_authorized_realms``.
|
||||
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The token as an urlencoded string.
|
||||
"""
|
||||
request.realms = self.request_validator.get_realms(
|
||||
|
@ -120,7 +119,8 @@ class AccessTokenEndpoint(BaseEndpoint):
|
|||
def validate_access_token_request(self, request):
|
||||
"""Validate an access token request.
|
||||
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:raises: OAuth1Error if the request is invalid.
|
||||
:returns: A tuple of 2 elements.
|
||||
1. The validation result (True or False).
|
||||
|
@ -180,7 +180,7 @@ class AccessTokenEndpoint(BaseEndpoint):
|
|||
# token credentials to the client, and ensure that the temporary
|
||||
# credentials have not expired or been used before. The server MUST
|
||||
# also verify the verification code received from the client.
|
||||
# .. _`Section 3.2`: http://tools.ietf.org/html/rfc5849#section-3.2
|
||||
# .. _`Section 3.2`: https://tools.ietf.org/html/rfc5849#section-3.2
|
||||
#
|
||||
# Note that early exit would enable resource owner authorization
|
||||
# verifier enumertion.
|
||||
|
|
|
@ -6,16 +6,12 @@ oauthlib.oauth1.rfc5849.endpoints.authorization
|
|||
This module is an implementation of various logic needed
|
||||
for signing and checking OAuth 1.0 RFC 5849 requests.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from oauthlib.common import Request, add_params_to_uri
|
||||
from oauthlib.common import add_params_to_uri
|
||||
|
||||
from .base import BaseEndpoint
|
||||
from .. import errors
|
||||
try:
|
||||
from urllib import urlencode
|
||||
except ImportError:
|
||||
from urllib.parse import urlencode
|
||||
from .base import BaseEndpoint
|
||||
|
||||
|
||||
class AuthorizationEndpoint(BaseEndpoint):
|
||||
|
@ -41,7 +37,8 @@ class AuthorizationEndpoint(BaseEndpoint):
|
|||
def create_verifier(self, request, credentials):
|
||||
"""Create and save a new request token.
|
||||
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:param credentials: A dict of extra token credentials.
|
||||
:returns: The verifier as a dict.
|
||||
"""
|
||||
|
|
|
@ -6,21 +6,20 @@ oauthlib.oauth1.rfc5849.endpoints.base
|
|||
This module is an implementation of various logic needed
|
||||
for signing and checking OAuth 1.0 RFC 5849 requests.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
from oauthlib.common import Request, generate_token
|
||||
from oauthlib.common import CaseInsensitiveDict, Request, generate_token
|
||||
|
||||
from .. import signature, utils, errors
|
||||
from .. import CONTENT_TYPE_FORM_URLENCODED
|
||||
from .. import SIGNATURE_HMAC, SIGNATURE_RSA
|
||||
from .. import SIGNATURE_TYPE_AUTH_HEADER
|
||||
from .. import SIGNATURE_TYPE_QUERY
|
||||
from .. import SIGNATURE_TYPE_BODY
|
||||
from .. import (
|
||||
CONTENT_TYPE_FORM_URLENCODED,
|
||||
SIGNATURE_HMAC_SHA1, SIGNATURE_HMAC_SHA256, SIGNATURE_HMAC_SHA512,
|
||||
SIGNATURE_RSA_SHA1, SIGNATURE_RSA_SHA256, SIGNATURE_RSA_SHA512,
|
||||
SIGNATURE_PLAINTEXT,
|
||||
SIGNATURE_TYPE_AUTH_HEADER, SIGNATURE_TYPE_BODY,
|
||||
SIGNATURE_TYPE_QUERY, errors, signature, utils)
|
||||
|
||||
|
||||
class BaseEndpoint(object):
|
||||
class BaseEndpoint:
|
||||
|
||||
def __init__(self, request_validator, token_generator=None):
|
||||
self.request_validator = request_validator
|
||||
|
@ -70,7 +69,7 @@ class BaseEndpoint(object):
|
|||
|
||||
def _create_request(self, uri, http_method, body, headers):
|
||||
# Only include body data from x-www-form-urlencoded requests
|
||||
headers = headers or {}
|
||||
headers = CaseInsensitiveDict(headers or {})
|
||||
if ("Content-Type" in headers and
|
||||
CONTENT_TYPE_FORM_URLENCODED in headers["Content-Type"]):
|
||||
request = Request(uri, http_method, body, headers)
|
||||
|
@ -130,11 +129,11 @@ class BaseEndpoint(object):
|
|||
# specification. Implementers should review the Security
|
||||
# Considerations section (`Section 4`_) before deciding on which
|
||||
# method to support.
|
||||
# .. _`Section 4`: http://tools.ietf.org/html/rfc5849#section-4
|
||||
# .. _`Section 4`: https://tools.ietf.org/html/rfc5849#section-4
|
||||
if (not request.signature_method in
|
||||
self.request_validator.allowed_signature_methods):
|
||||
raise errors.InvalidSignatureMethodError(
|
||||
description="Invalid signature, %s not in %r." % (
|
||||
description="Invalid signature, {} not in {!r}.".format(
|
||||
request.signature_method,
|
||||
self.request_validator.allowed_signature_methods))
|
||||
|
||||
|
@ -182,35 +181,65 @@ class BaseEndpoint(object):
|
|||
|
||||
def _check_signature(self, request, is_token_request=False):
|
||||
# ---- RSA Signature verification ----
|
||||
if request.signature_method == SIGNATURE_RSA:
|
||||
if request.signature_method == SIGNATURE_RSA_SHA1 or \
|
||||
request.signature_method == SIGNATURE_RSA_SHA256 or \
|
||||
request.signature_method == SIGNATURE_RSA_SHA512:
|
||||
# RSA-based signature method
|
||||
|
||||
# The server verifies the signature per `[RFC3447] section 8.2.2`_
|
||||
# .. _`[RFC3447] section 8.2.2`: http://tools.ietf.org/html/rfc3447#section-8.2.1
|
||||
# .. _`[RFC3447] section 8.2.2`: https://tools.ietf.org/html/rfc3447#section-8.2.1
|
||||
|
||||
rsa_key = self.request_validator.get_rsa_key(
|
||||
request.client_key, request)
|
||||
valid_signature = signature.verify_rsa_sha1(request, rsa_key)
|
||||
|
||||
if request.signature_method == SIGNATURE_RSA_SHA1:
|
||||
valid_signature = signature.verify_rsa_sha1(request, rsa_key)
|
||||
elif request.signature_method == SIGNATURE_RSA_SHA256:
|
||||
valid_signature = signature.verify_rsa_sha256(request, rsa_key)
|
||||
elif request.signature_method == SIGNATURE_RSA_SHA512:
|
||||
valid_signature = signature.verify_rsa_sha512(request, rsa_key)
|
||||
else:
|
||||
valid_signature = False
|
||||
|
||||
# ---- HMAC or Plaintext Signature verification ----
|
||||
else:
|
||||
# Non-RSA based signature method
|
||||
|
||||
# Servers receiving an authenticated request MUST validate it by:
|
||||
# Recalculating the request signature independently as described in
|
||||
# `Section 3.4`_ and comparing it to the value received from the
|
||||
# client via the "oauth_signature" parameter.
|
||||
# .. _`Section 3.4`: http://tools.ietf.org/html/rfc5849#section-3.4
|
||||
# .. _`Section 3.4`: https://tools.ietf.org/html/rfc5849#section-3.4
|
||||
|
||||
client_secret = self.request_validator.get_client_secret(
|
||||
request.client_key, request)
|
||||
|
||||
resource_owner_secret = None
|
||||
if request.resource_owner_key:
|
||||
if is_token_request:
|
||||
resource_owner_secret = self.request_validator.get_request_token_secret(
|
||||
request.client_key, request.resource_owner_key, request)
|
||||
resource_owner_secret = \
|
||||
self.request_validator.get_request_token_secret(
|
||||
request.client_key, request.resource_owner_key,
|
||||
request)
|
||||
else:
|
||||
resource_owner_secret = self.request_validator.get_access_token_secret(
|
||||
request.client_key, request.resource_owner_key, request)
|
||||
resource_owner_secret = \
|
||||
self.request_validator.get_access_token_secret(
|
||||
request.client_key, request.resource_owner_key,
|
||||
request)
|
||||
|
||||
if request.signature_method == SIGNATURE_HMAC:
|
||||
valid_signature = signature.verify_hmac_sha1(request,
|
||||
client_secret, resource_owner_secret)
|
||||
if request.signature_method == SIGNATURE_HMAC_SHA1:
|
||||
valid_signature = signature.verify_hmac_sha1(
|
||||
request, client_secret, resource_owner_secret)
|
||||
elif request.signature_method == SIGNATURE_HMAC_SHA256:
|
||||
valid_signature = signature.verify_hmac_sha256(
|
||||
request, client_secret, resource_owner_secret)
|
||||
elif request.signature_method == SIGNATURE_HMAC_SHA512:
|
||||
valid_signature = signature.verify_hmac_sha512(
|
||||
request, client_secret, resource_owner_secret)
|
||||
elif request.signature_method == SIGNATURE_PLAINTEXT:
|
||||
valid_signature = signature.verify_plaintext(
|
||||
request, client_secret, resource_owner_secret)
|
||||
else:
|
||||
valid_signature = signature.verify_plaintext(request,
|
||||
client_secret, resource_owner_secret)
|
||||
valid_signature = False
|
||||
|
||||
return valid_signature
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from . import RequestTokenEndpoint, AuthorizationEndpoint
|
||||
from . import AccessTokenEndpoint, ResourceEndpoint
|
||||
from . import (
|
||||
AccessTokenEndpoint, AuthorizationEndpoint, RequestTokenEndpoint,
|
||||
ResourceEndpoint,
|
||||
)
|
||||
|
||||
|
||||
class WebApplicationServer(RequestTokenEndpoint, AuthorizationEndpoint,
|
||||
|
|
|
@ -8,14 +8,12 @@ OAuth 1.0 RFC 5849. It validates the correctness of request token requests,
|
|||
creates and persists tokens as well as create the proper response to be
|
||||
returned to the client.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from oauthlib.common import urlencode
|
||||
|
||||
from .base import BaseEndpoint
|
||||
from .. import errors
|
||||
from .base import BaseEndpoint
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -34,7 +32,8 @@ class RequestTokenEndpoint(BaseEndpoint):
|
|||
def create_request_token(self, request, credentials):
|
||||
"""Create and save a new request token.
|
||||
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:param credentials: A dict of extra token credentials.
|
||||
:returns: The token as an urlencoded string.
|
||||
"""
|
||||
|
@ -111,7 +110,8 @@ class RequestTokenEndpoint(BaseEndpoint):
|
|||
def validate_request_token_request(self, request):
|
||||
"""Validate a request token request.
|
||||
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:raises: OAuth1Error if the request is invalid.
|
||||
:returns: A tuple of 2 elements.
|
||||
1. The validation result (True or False).
|
||||
|
@ -127,7 +127,7 @@ class RequestTokenEndpoint(BaseEndpoint):
|
|||
request.client_key, request)
|
||||
if not self.request_validator.check_realms(request.realms):
|
||||
raise errors.InvalidRequestError(
|
||||
description='Invalid realm %s. Allowed are %r.' % (
|
||||
description='Invalid realm {}. Allowed are {!r}.'.format(
|
||||
request.realms, self.request_validator.realms))
|
||||
|
||||
if not request.redirect_uri:
|
||||
|
@ -156,7 +156,7 @@ class RequestTokenEndpoint(BaseEndpoint):
|
|||
# However they could be seen as a scope or realm to which the
|
||||
# client has access and as such every client should be checked
|
||||
# to ensure it is authorized access to that scope or realm.
|
||||
# .. _`realm`: http://tools.ietf.org/html/rfc2617#section-1.2
|
||||
# .. _`realm`: https://tools.ietf.org/html/rfc2617#section-1.2
|
||||
#
|
||||
# Note that early exit would enable client realm access enumeration.
|
||||
#
|
||||
|
@ -178,7 +178,7 @@ class RequestTokenEndpoint(BaseEndpoint):
|
|||
|
||||
# Callback is normally never required, except for requests for
|
||||
# a Temporary Credential as described in `Section 2.1`_
|
||||
# .._`Section 2.1`: http://tools.ietf.org/html/rfc5849#section-2.1
|
||||
# .._`Section 2.1`: https://tools.ietf.org/html/rfc5849#section-2.1
|
||||
valid_redirect = self.request_validator.validate_redirect_uri(
|
||||
request.client_key, request.redirect_uri, request)
|
||||
if not request.redirect_uri:
|
||||
|
|
|
@ -6,12 +6,10 @@ oauthlib.oauth1.rfc5849.endpoints.resource
|
|||
This module is an implementation of the resource protection provider logic of
|
||||
OAuth 1.0 RFC 5849.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from .base import BaseEndpoint
|
||||
from .. import errors
|
||||
from .base import BaseEndpoint
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -119,7 +117,7 @@ class ResourceEndpoint(BaseEndpoint):
|
|||
# However they could be seen as a scope or realm to which the
|
||||
# client has access and as such every client should be checked
|
||||
# to ensure it is authorized access to that scope or realm.
|
||||
# .. _`realm`: http://tools.ietf.org/html/rfc2617#section-1.2
|
||||
# .. _`realm`: https://tools.ietf.org/html/rfc2617#section-1.2
|
||||
#
|
||||
# Note that early exit would enable client realm access enumeration.
|
||||
#
|
||||
|
|
|
@ -6,12 +6,10 @@ oauthlib.oauth1.rfc5849.endpoints.signature_only
|
|||
This module is an implementation of the signing logic of OAuth 1.0 RFC 5849.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from .base import BaseEndpoint
|
||||
from .. import errors
|
||||
from .base import BaseEndpoint
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -34,17 +32,22 @@ class SignatureOnlyEndpoint(BaseEndpoint):
|
|||
"""
|
||||
try:
|
||||
request = self._create_request(uri, http_method, body, headers)
|
||||
except errors.OAuth1Error:
|
||||
except errors.OAuth1Error as err:
|
||||
log.info(
|
||||
'Exception caught while validating request, %s.' % err)
|
||||
return False, None
|
||||
|
||||
try:
|
||||
self._check_transport_security(request)
|
||||
self._check_mandatory_parameters(request)
|
||||
except errors.OAuth1Error:
|
||||
except errors.OAuth1Error as err:
|
||||
log.info(
|
||||
'Exception caught while validating request, %s.' % err)
|
||||
return False, request
|
||||
|
||||
if not self.request_validator.validate_timestamp_and_nonce(
|
||||
request.client_key, request.timestamp, request.nonce, request):
|
||||
log.debug('[Failure] verification failed: timestamp/nonce')
|
||||
return False, request
|
||||
|
||||
# The server SHOULD return a 401 (Unauthorized) status code when
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
oauthlib.oauth1.rfc5849.errors
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -6,9 +5,7 @@ oauthlib.oauth1.rfc5849.errors
|
|||
Error used both by OAuth 1 clients and provicers to represent the spec
|
||||
defined error responses for all four core grant types.
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from oauthlib.common import urlencode, add_params_to_uri
|
||||
from oauthlib.common import add_params_to_uri, urlencode
|
||||
|
||||
|
||||
class OAuth1Error(Exception):
|
||||
|
@ -37,10 +34,10 @@ class OAuth1Error(Exception):
|
|||
request: Oauthlib Request object
|
||||
"""
|
||||
self.description = description or self.description
|
||||
message = '(%s) %s' % (self.error, self.description)
|
||||
message = '({}) {}'.format(self.error, self.description)
|
||||
if request:
|
||||
message += ' ' + repr(request)
|
||||
super(OAuth1Error, self).__init__(message)
|
||||
super().__init__(message)
|
||||
|
||||
self.uri = uri
|
||||
self.status_code = status_code
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
oauthlib.parameters
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This module contains methods related to `section 3.5`_ of the OAuth 1.0a spec.
|
||||
|
||||
.. _`section 3.5`: http://tools.ietf.org/html/rfc5849#section-3.5
|
||||
.. _`section 3.5`: https://tools.ietf.org/html/rfc5849#section-3.5
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
try:
|
||||
from urlparse import urlparse, urlunparse
|
||||
except ImportError:
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
from . import utils
|
||||
from oauthlib.common import extract_params, urlencode
|
||||
|
||||
from . import utils
|
||||
|
||||
|
||||
# TODO: do we need filter_params now that oauth_params are handled by Request?
|
||||
# We can easily pass in just oauth protocol params.
|
||||
|
@ -40,8 +36,8 @@ def prepare_headers(oauth_params, headers=None, realm=None):
|
|||
oauth_version="1.0"
|
||||
|
||||
|
||||
.. _`section 3.5.1`: http://tools.ietf.org/html/rfc5849#section-3.5.1
|
||||
.. _`RFC2617`: http://tools.ietf.org/html/rfc2617
|
||||
.. _`section 3.5.1`: https://tools.ietf.org/html/rfc5849#section-3.5.1
|
||||
.. _`RFC2617`: https://tools.ietf.org/html/rfc2617
|
||||
"""
|
||||
headers = headers or {}
|
||||
|
||||
|
@ -52,28 +48,28 @@ def prepare_headers(oauth_params, headers=None, realm=None):
|
|||
# 1. Parameter names and values are encoded per Parameter Encoding
|
||||
# (`Section 3.6`_)
|
||||
#
|
||||
# .. _`Section 3.6`: http://tools.ietf.org/html/rfc5849#section-3.6
|
||||
# .. _`Section 3.6`: https://tools.ietf.org/html/rfc5849#section-3.6
|
||||
escaped_name = utils.escape(oauth_parameter_name)
|
||||
escaped_value = utils.escape(value)
|
||||
|
||||
# 2. Each parameter's name is immediately followed by an "=" character
|
||||
# (ASCII code 61), a """ character (ASCII code 34), the parameter
|
||||
# value (MAY be empty), and another """ character (ASCII code 34).
|
||||
part = '{0}="{1}"'.format(escaped_name, escaped_value)
|
||||
part = '{}="{}"'.format(escaped_name, escaped_value)
|
||||
|
||||
authorization_header_parameters_parts.append(part)
|
||||
|
||||
# 3. Parameters are separated by a "," character (ASCII code 44) and
|
||||
# OPTIONAL linear whitespace per `RFC2617`_.
|
||||
#
|
||||
# .. _`RFC2617`: http://tools.ietf.org/html/rfc2617
|
||||
# .. _`RFC2617`: https://tools.ietf.org/html/rfc2617
|
||||
authorization_header_parameters = ', '.join(
|
||||
authorization_header_parameters_parts)
|
||||
|
||||
# 4. The OPTIONAL "realm" parameter MAY be added and interpreted per
|
||||
# `RFC2617 section 1.2`_.
|
||||
#
|
||||
# .. _`RFC2617 section 1.2`: http://tools.ietf.org/html/rfc2617#section-1.2
|
||||
# .. _`RFC2617 section 1.2`: https://tools.ietf.org/html/rfc2617#section-1.2
|
||||
if realm:
|
||||
# NOTE: realm should *not* be escaped
|
||||
authorization_header_parameters = ('realm="%s", ' % realm +
|
||||
|
@ -96,8 +92,8 @@ def _append_params(oauth_params, params):
|
|||
|
||||
Per `section 3.5.2`_ and `3.5.3`_ of the spec.
|
||||
|
||||
.. _`section 3.5.2`: http://tools.ietf.org/html/rfc5849#section-3.5.2
|
||||
.. _`3.5.3`: http://tools.ietf.org/html/rfc5849#section-3.5.3
|
||||
.. _`section 3.5.2`: https://tools.ietf.org/html/rfc5849#section-3.5.2
|
||||
.. _`3.5.3`: https://tools.ietf.org/html/rfc5849#section-3.5.3
|
||||
|
||||
"""
|
||||
merged = list(params)
|
||||
|
@ -115,7 +111,7 @@ def prepare_form_encoded_body(oauth_params, body):
|
|||
|
||||
Per `section 3.5.2`_ of the spec.
|
||||
|
||||
.. _`section 3.5.2`: http://tools.ietf.org/html/rfc5849#section-3.5.2
|
||||
.. _`section 3.5.2`: https://tools.ietf.org/html/rfc5849#section-3.5.2
|
||||
|
||||
"""
|
||||
# append OAuth params to the existing body
|
||||
|
@ -127,7 +123,7 @@ def prepare_request_uri_query(oauth_params, uri):
|
|||
|
||||
Per `section 3.5.3`_ of the spec.
|
||||
|
||||
.. _`section 3.5.3`: http://tools.ietf.org/html/rfc5849#section-3.5.3
|
||||
.. _`section 3.5.3`: https://tools.ietf.org/html/rfc5849#section-3.5.3
|
||||
|
||||
"""
|
||||
# append OAuth params to the existing set of query components
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
oauthlib.oauth1.rfc5849
|
||||
~~~~~~~~~~~~~~
|
||||
|
@ -6,12 +5,10 @@ oauthlib.oauth1.rfc5849
|
|||
This module is an implementation of various logic needed
|
||||
for signing and checking OAuth 1.0 RFC 5849 requests.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from . import SIGNATURE_METHODS, utils
|
||||
|
||||
|
||||
class RequestValidator(object):
|
||||
class RequestValidator:
|
||||
|
||||
"""A validator/datastore interaction base class for OAuth 1 providers.
|
||||
|
||||
|
@ -107,7 +104,7 @@ class RequestValidator(object):
|
|||
their use more straightforward and as such it could be worth reading what
|
||||
follows in chronological order.
|
||||
|
||||
.. _`whitelisting or blacklisting`: http://www.schneier.com/blog/archives/2011/01/whitelisting_vs.html
|
||||
.. _`whitelisting or blacklisting`: https://www.schneier.com/blog/archives/2011/01/whitelisting_vs.html
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
@ -195,7 +192,15 @@ class RequestValidator(object):
|
|||
|
||||
def check_realms(self, realms):
|
||||
"""Check that the realm is one of a set allowed realms."""
|
||||
return all((r in self.realms for r in realms))
|
||||
return all(r in self.realms for r in realms)
|
||||
|
||||
def _subclass_must_implement(self, fn):
|
||||
"""
|
||||
Returns a NotImplementedError for a function that should be implemented.
|
||||
:param fn: name of the function
|
||||
"""
|
||||
m = "Missing function implementation in {}: {}".format(type(self), fn)
|
||||
return NotImplementedError(m)
|
||||
|
||||
@property
|
||||
def dummy_client(self):
|
||||
|
@ -219,7 +224,7 @@ class RequestValidator(object):
|
|||
* ResourceEndpoint
|
||||
* SignatureOnlyEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("dummy_client")
|
||||
|
||||
@property
|
||||
def dummy_request_token(self):
|
||||
|
@ -235,7 +240,7 @@ class RequestValidator(object):
|
|||
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("dummy_request_token")
|
||||
|
||||
@property
|
||||
def dummy_access_token(self):
|
||||
|
@ -251,13 +256,14 @@ class RequestValidator(object):
|
|||
|
||||
* ResourceEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("dummy_access_token")
|
||||
|
||||
def get_client_secret(self, client_key, request):
|
||||
"""Retrieves the client secret associated with the client key.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The client secret as a string.
|
||||
|
||||
This method must allow the use of a dummy client_key value.
|
||||
|
@ -286,14 +292,15 @@ class RequestValidator(object):
|
|||
* ResourceEndpoint
|
||||
* SignatureOnlyEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement('get_client_secret')
|
||||
|
||||
def get_request_token_secret(self, client_key, token, request):
|
||||
"""Retrieves the shared secret associated with the request token.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param token: The request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The token secret as a string.
|
||||
|
||||
This method must allow the use of a dummy values and the running time
|
||||
|
@ -318,14 +325,15 @@ class RequestValidator(object):
|
|||
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement('get_request_token_secret')
|
||||
|
||||
def get_access_token_secret(self, client_key, token, request):
|
||||
"""Retrieves the shared secret associated with the access token.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param token: The access token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The token secret as a string.
|
||||
|
||||
This method must allow the use of a dummy values and the running time
|
||||
|
@ -350,13 +358,14 @@ class RequestValidator(object):
|
|||
|
||||
* ResourceEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("get_access_token_secret")
|
||||
|
||||
def get_default_realms(self, client_key, request):
|
||||
"""Get the default realms for a client.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The list of default realms associated with the client.
|
||||
|
||||
The list of default realms will be set during client registration and
|
||||
|
@ -366,13 +375,14 @@ class RequestValidator(object):
|
|||
|
||||
* RequestTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("get_default_realms")
|
||||
|
||||
def get_realms(self, token, request):
|
||||
"""Get realms associated with a request token.
|
||||
|
||||
:param token: The request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The list of realms associated with the request token.
|
||||
|
||||
This method is used by
|
||||
|
@ -380,13 +390,14 @@ class RequestValidator(object):
|
|||
* AuthorizationEndpoint
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("get_realms")
|
||||
|
||||
def get_redirect_uri(self, token, request):
|
||||
"""Get the redirect URI associated with a request token.
|
||||
|
||||
:param token: The request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The redirect URI associated with the request token.
|
||||
|
||||
It may be desirable to return a custom URI if the redirect is set to "oob".
|
||||
|
@ -397,13 +408,14 @@ class RequestValidator(object):
|
|||
|
||||
* AuthorizationEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("get_redirect_uri")
|
||||
|
||||
def get_rsa_key(self, client_key, request):
|
||||
"""Retrieves a previously stored client provided RSA key.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: The rsa public key as a string.
|
||||
|
||||
This method must allow the use of a dummy client_key value. Fetching
|
||||
|
@ -420,14 +432,15 @@ class RequestValidator(object):
|
|||
* ResourceEndpoint
|
||||
* SignatureOnlyEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("get_rsa_key")
|
||||
|
||||
def invalidate_request_token(self, client_key, request_token, request):
|
||||
"""Invalidates a used request token.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param request_token: The request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: None
|
||||
|
||||
Per `Section 2.3`__ of the spec:
|
||||
|
@ -435,7 +448,7 @@ class RequestValidator(object):
|
|||
"The server MUST (...) ensure that the temporary
|
||||
credentials have not expired or been used before."
|
||||
|
||||
.. _`Section 2.3`: http://tools.ietf.org/html/rfc5849#section-2.3
|
||||
.. _`Section 2.3`: https://tools.ietf.org/html/rfc5849#section-2.3
|
||||
|
||||
This method should ensure that provided token won't validate anymore.
|
||||
It can be simply removing RequestToken from storage or setting
|
||||
|
@ -446,13 +459,14 @@ class RequestValidator(object):
|
|||
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("invalidate_request_token")
|
||||
|
||||
def validate_client_key(self, client_key, request):
|
||||
"""Validates that supplied client key is a registered and valid client.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
Note that if the dummy client is supplied it should validate in same
|
||||
|
@ -482,14 +496,15 @@ class RequestValidator(object):
|
|||
* ResourceEndpoint
|
||||
* SignatureOnlyEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_client_key")
|
||||
|
||||
def validate_request_token(self, client_key, token, request):
|
||||
"""Validates that supplied request token is registered and valid.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param token: The request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
Note that if the dummy request_token is supplied it should validate in
|
||||
|
@ -516,14 +531,15 @@ class RequestValidator(object):
|
|||
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_request_token")
|
||||
|
||||
def validate_access_token(self, client_key, token, request):
|
||||
"""Validates that supplied access token is registered and valid.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param token: The access token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
Note that if the dummy access token is supplied it should validate in
|
||||
|
@ -550,7 +566,7 @@ class RequestValidator(object):
|
|||
|
||||
* ResourceEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_access_token")
|
||||
|
||||
def validate_timestamp_and_nonce(self, client_key, timestamp, nonce,
|
||||
request, request_token=None, access_token=None):
|
||||
|
@ -561,7 +577,8 @@ class RequestValidator(object):
|
|||
:param nonce: The ``oauth_nonce`` parameter.
|
||||
:param request_token: Request token string, if any.
|
||||
:param access_token: Access token string, if any.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
Per `Section 3.3`_ of the spec.
|
||||
|
@ -572,7 +589,7 @@ class RequestValidator(object):
|
|||
channel. The nonce value MUST be unique across all requests with the
|
||||
same timestamp, client credentials, and token combinations."
|
||||
|
||||
.. _`Section 3.3`: http://tools.ietf.org/html/rfc5849#section-3.3
|
||||
.. _`Section 3.3`: https://tools.ietf.org/html/rfc5849#section-3.3
|
||||
|
||||
One of the first validation checks that will be made is for the validity
|
||||
of the nonce and timestamp, which are associated with a client key and
|
||||
|
@ -600,7 +617,7 @@ class RequestValidator(object):
|
|||
* ResourceEndpoint
|
||||
* SignatureOnlyEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_timestamp_and_nonce")
|
||||
|
||||
def validate_redirect_uri(self, client_key, redirect_uri, request):
|
||||
"""Validates the client supplied redirection URI.
|
||||
|
@ -608,7 +625,8 @@ class RequestValidator(object):
|
|||
:param client_key: The client/consumer key.
|
||||
:param redirect_uri: The URI the client which to redirect back to after
|
||||
authorization is successful.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
It is highly recommended that OAuth providers require their clients
|
||||
|
@ -633,14 +651,15 @@ class RequestValidator(object):
|
|||
|
||||
* RequestTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_redirect_uri")
|
||||
|
||||
def validate_requested_realms(self, client_key, realms, request):
|
||||
"""Validates that the client may request access to the realm.
|
||||
|
||||
:param client_key: The client/consumer key.
|
||||
:param realms: The list of realms that client is requesting access to.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
This method is invoked when obtaining a request token and should
|
||||
|
@ -651,7 +670,7 @@ class RequestValidator(object):
|
|||
|
||||
* RequestTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_requested_realms")
|
||||
|
||||
def validate_realms(self, client_key, token, request, uri=None,
|
||||
realms=None):
|
||||
|
@ -659,7 +678,8 @@ class RequestValidator(object):
|
|||
|
||||
:param client_key: The client/consumer key.
|
||||
:param token: A request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:param uri: The URI the realms is protecting.
|
||||
:param realms: A list of realms that must have been granted to
|
||||
the access token.
|
||||
|
@ -685,7 +705,7 @@ class RequestValidator(object):
|
|||
|
||||
* ResourceEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_realms")
|
||||
|
||||
def validate_verifier(self, client_key, token, verifier, request):
|
||||
"""Validates a verification code.
|
||||
|
@ -693,7 +713,8 @@ class RequestValidator(object):
|
|||
:param client_key: The client/consumer key.
|
||||
:param token: A request token string.
|
||||
:param verifier: The authorization verifier string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
OAuth providers issue a verification code to clients after the
|
||||
|
@ -716,13 +737,14 @@ class RequestValidator(object):
|
|||
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("validate_verifier")
|
||||
|
||||
def verify_request_token(self, token, request):
|
||||
"""Verify that the given OAuth1 request token is valid.
|
||||
|
||||
:param token: A request token string.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
This method is used only in AuthorizationEndpoint to check whether the
|
||||
|
@ -734,14 +756,15 @@ class RequestValidator(object):
|
|||
|
||||
* AuthorizationEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("verify_request_token")
|
||||
|
||||
def verify_realms(self, token, realms, request):
|
||||
"""Verify authorized realms to see if they match those given to token.
|
||||
|
||||
:param token: An access token string.
|
||||
:param realms: A list of realms the client attempts to access.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
:returns: True or False
|
||||
|
||||
This prevents the list of authorized realms sent by the client during
|
||||
|
@ -757,13 +780,14 @@ class RequestValidator(object):
|
|||
|
||||
* AuthorizationEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("verify_realms")
|
||||
|
||||
def save_access_token(self, token, request):
|
||||
"""Save an OAuth1 access token.
|
||||
|
||||
:param token: A dict with token credentials.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
|
||||
The token dictionary will at minimum include
|
||||
|
||||
|
@ -780,13 +804,14 @@ class RequestValidator(object):
|
|||
|
||||
* AccessTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("save_access_token")
|
||||
|
||||
def save_request_token(self, token, request):
|
||||
"""Save an OAuth1 request token.
|
||||
|
||||
:param token: A dict with token credentials.
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
|
||||
The token dictionary will at minimum include
|
||||
|
||||
|
@ -800,7 +825,7 @@ class RequestValidator(object):
|
|||
|
||||
* RequestTokenEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("save_request_token")
|
||||
|
||||
def save_verifier(self, token, verifier, request):
|
||||
"""Associate an authorization verifier with a request token.
|
||||
|
@ -808,7 +833,8 @@ class RequestValidator(object):
|
|||
:param token: A request token string.
|
||||
:param verifier A dictionary containing the oauth_verifier and
|
||||
oauth_token
|
||||
:param request: An oauthlib.common.Request object.
|
||||
:param request: OAuthlib request.
|
||||
:type request: oauthlib.common.Request
|
||||
|
||||
We need to associate verifiers with tokens for validation during the
|
||||
access token request.
|
||||
|
@ -820,4 +846,4 @@ class RequestValidator(object):
|
|||
|
||||
* AuthorizationEndpoint
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this function.")
|
||||
raise self._subclass_must_implement("save_verifier")
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
oauthlib.utils
|
||||
~~~~~~~~~~~~~~
|
||||
|
@ -6,14 +5,9 @@ oauthlib.utils
|
|||
This module contains utility methods used by various parts of the OAuth
|
||||
spec.
|
||||
"""
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
import urllib.request as urllib2
|
||||
|
||||
try:
|
||||
import urllib2
|
||||
except ImportError:
|
||||
import urllib.request as urllib2
|
||||
|
||||
from oauthlib.common import quote, unquote, bytes_type, unicode_type
|
||||
from oauthlib.common import quote, unquote
|
||||
|
||||
UNICODE_ASCII_CHARACTER_SET = ('abcdefghijklmnopqrstuvwxyz'
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
@ -48,19 +42,19 @@ def escape(u):
|
|||
|
||||
Per `section 3.6`_ of the spec.
|
||||
|
||||
.. _`section 3.6`: http://tools.ietf.org/html/rfc5849#section-3.6
|
||||
.. _`section 3.6`: https://tools.ietf.org/html/rfc5849#section-3.6
|
||||
|
||||
"""
|
||||
if not isinstance(u, unicode_type):
|
||||
if not isinstance(u, str):
|
||||
raise ValueError('Only unicode objects are escapable. ' +
|
||||
'Got %s of type %s.' % (u, type(u)))
|
||||
'Got {!r} of type {}.'.format(u, type(u)))
|
||||
# Letters, digits, and the characters '_.-' are already treated as safe
|
||||
# by urllib.quote(). We need to add '~' to fully support rfc5849.
|
||||
return quote(u, safe=b'~')
|
||||
|
||||
|
||||
def unescape(u):
|
||||
if not isinstance(u, unicode_type):
|
||||
if not isinstance(u, str):
|
||||
raise ValueError('Only unicode objects are unescapable.')
|
||||
return unquote(u)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue