diff options
author | Ib Lundgren <ib.lundgren@gmail.com> | 2014-09-24 17:32:39 +0100 |
---|---|---|
committer | Ib Lundgren <ib.lundgren@gmail.com> | 2014-09-24 17:32:39 +0100 |
commit | 2d7dab66b589159712f96bd0086f45ae3c32216d (patch) | |
tree | 1e24d34ada1982ef2865530ff18d228164c0d35a | |
parent | 39013947bd2e242dda85fb0f150c49be23fd7510 (diff) | |
download | oauthlib-2d7dab66b589159712f96bd0086f45ae3c32216d.tar.gz |
Auto pep8 changes throughout the code base.
36 files changed, 390 insertions, 291 deletions
diff --git a/oauthlib/__init__.py b/oauthlib/__init__.py index c70b46a..707cb9c 100644 --- a/oauthlib/__init__.py +++ b/oauthlib/__init__.py @@ -17,8 +17,9 @@ import logging try: # Python 2.7+ from logging import NullHandler except ImportError: - class NullHandler(logging.Handler): - def emit(self, record): - pass + class NullHandler(logging.Handler): + + def emit(self, record): + pass logging.getLogger('oauthlib').addHandler(NullHandler()) diff --git a/oauthlib/common.py b/oauthlib/common.py index d3e2edb..b200a9a 100644 --- a/oauthlib/common.py +++ b/oauthlib/common.py @@ -33,7 +33,7 @@ UNICODE_ASCII_CHARACTER_SET = ('abcdefghijklmnopqrstuvwxyz' '0123456789') CLIENT_ID_CHARACTER_SET = (r' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN' - 'OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}') + 'OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}') always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -147,7 +147,8 @@ def urldecode(query): # Python 3.3 however # >>> urllib.parse.parse_qsl(u'%E5%95%A6%E5%95%A6') # u'\u5566\u5566' - query = query.encode('utf-8') if not PY3 and isinstance(query, unicode_type) else query + query = query.encode( + 'utf-8') if not PY3 and isinstance(query, unicode_type) else query # We want to allow queries such as "c2" whereas urlparse.parse_qsl # with the strict_parsing flag will not. params = urlparse.parse_qsl(query, keep_blank_values=True) @@ -252,7 +253,7 @@ def verify_signed_token(private_pem, token): public_key = RSA.importKey(private_pem).publickey() try: - #return jwt.verify_jwt(token.encode(), public_key) + # return jwt.verify_jwt(token.encode(), public_key) return jwt.decode(token, public_key) except: raise Exception @@ -330,6 +331,7 @@ def to_unicode(data, encoding='UTF-8'): class CaseInsensitiveDict(dict): + """Basic case insensitive dict with strings only keys.""" proxy = {} @@ -360,6 +362,7 @@ class CaseInsensitiveDict(dict): class Request(object): + """A malleable representation of a signable HTTP request. Body argument may contain any data, but parameters will only be decoded if @@ -374,7 +377,7 @@ class Request(object): """ def __init__(self, uri, http_method='GET', body=None, headers=None, - encoding='utf-8'): + encoding='utf-8'): # Convert to unicode using encoding if given, else assume unicode encode = lambda x: to_unicode(x, encoding) if encoding else x @@ -393,10 +396,9 @@ class Request(object): def __getattr__(self, name): return self._params.get(name, None) - def __repr__(self): return '<oauthlib.Request url="%s", http_method="%s", headers="%s", body="%s">' % ( - self.uri, self.http_method, self.headers, self.body) + self.uri, self.http_method, self.headers, self.body) @property def uri_query(self): @@ -412,7 +414,8 @@ class Request(object): @property def duplicate_params(self): seen_keys = collections.defaultdict(int) - all_keys = (p[0] for p in (self.decoded_body or []) + self.uri_query_params) + all_keys = (p[0] + for p in (self.decoded_body or []) + self.uri_query_params) for k in all_keys: seen_keys[k] += 1 return [k for k, c in seen_keys.items() if c > 1] diff --git a/oauthlib/oauth1/rfc5849/__init__.py b/oauthlib/oauth1/rfc5849/__init__.py index fbf6429..7ecc69e 100644 --- a/oauthlib/oauth1/rfc5849/__init__.py +++ b/oauthlib/oauth1/rfc5849/__init__.py @@ -39,6 +39,7 @@ CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' class Client(object): + """A client used to sign OAuth 1.0 RFC 5849 requests.""" SIGNATURE_METHODS = { SIGNATURE_HMAC: signature.sign_hmac_sha1_with_client, @@ -51,15 +52,15 @@ class Client(object): cls.SIGNATURE_METHODS[method_name] = method_callback def __init__(self, client_key, - client_secret=None, - resource_owner_key=None, - resource_owner_secret=None, - callback_uri=None, - signature_method=SIGNATURE_HMAC, - signature_type=SIGNATURE_TYPE_AUTH_HEADER, - rsa_key=None, verifier=None, realm=None, - encoding='utf-8', decoding=None, - nonce=None, timestamp=None): + client_secret=None, + resource_owner_key=None, + resource_owner_secret=None, + callback_uri=None, + signature_method=SIGNATURE_HMAC, + signature_type=SIGNATURE_TYPE_AUTH_HEADER, + rsa_key=None, verifier=None, realm=None, + encoding='utf-8', decoding=None, + nonce=None, timestamp=None): """Create an OAuth 1 client. :param client_key: Client key (consumer key), mandatory. @@ -101,12 +102,14 @@ class Client(object): self.timestamp = encode(timestamp) if self.signature_method == SIGNATURE_RSA and self.rsa_key is None: - raise ValueError('rsa_key is required when using RSA signature method.') + raise ValueError( + 'rsa_key is required when using RSA signature method.') def __repr__(self): attrs = vars(self).copy() attrs['client_secret'] = '****' if attrs['client_secret'] else None - attrs['resource_owner_secret'] = '****' if attrs['resource_owner_secret'] 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) @@ -123,7 +126,7 @@ class Client(object): if self.signature_method == SIGNATURE_PLAINTEXT: # fast-path return signature.sign_plaintext(self.client_secret, - self.resource_owner_secret) + self.resource_owner_secret) uri, headers, body = self._render(request) @@ -135,12 +138,12 @@ class Client(object): normalized_params = signature.normalize_parameters(collected_params) normalized_uri = signature.normalize_base_string_uri(uri, - headers.get('Host', None)) + headers.get('Host', None)) log.debug("Normalized params: {0}".format(normalized_params)) log.debug("Normalized URI: {0}".format(normalized_uri)) base_string = signature.construct_base_string(request.http_method, - normalized_uri, normalized_params) + normalized_uri, normalized_params) log.debug("Base signing string: {0}".format(base_string)) @@ -196,14 +199,17 @@ class Client(object): # like the spec requires. This would be a fundamental change though, and # I'm not sure how I feel about it. if self.signature_type == SIGNATURE_TYPE_AUTH_HEADER: - headers = parameters.prepare_headers(request.oauth_params, request.headers, realm=realm) + headers = parameters.prepare_headers( + request.oauth_params, request.headers, realm=realm) elif self.signature_type == SIGNATURE_TYPE_BODY and request.decoded_body is not None: - body = parameters.prepare_form_encoded_body(request.oauth_params, request.decoded_body) + body = parameters.prepare_form_encoded_body( + request.oauth_params, request.decoded_body) if formencode: body = urlencode(body) headers['Content-Type'] = 'application/x-www-form-urlencoded' elif self.signature_type == SIGNATURE_TYPE_QUERY: - uri = parameters.prepare_request_uri_query(request.oauth_params, request.uri) + uri = parameters.prepare_request_uri_query( + request.oauth_params, request.uri) else: raise ValueError('Unknown signature type specified.') @@ -253,16 +259,19 @@ class Client(object): # if [...]: # * The entity-body is single-part. if multipart and has_params: - raise ValueError("Headers indicate a multipart body but body contains parameters.") + raise ValueError( + "Headers indicate a multipart body but body contains parameters.") # * The entity-body follows the encoding requirements of the # "application/x-www-form-urlencoded" content-type as defined by # [W3C.REC-html40-19980424]. elif should_have_params and not has_params: - raise ValueError("Headers indicate a formencoded body but body was not decodable.") + raise ValueError( + "Headers indicate a formencoded body but body was not decodable.") # * The HTTP request entity-header includes the "Content-Type" # 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 not set.") + raise ValueError( + "Body contains parameters but Content-Type header was not set.") # 3.5.2. Form-Encoded Body # Protocol parameters can be transmitted in the HTTP request entity- @@ -275,7 +284,8 @@ class Client(object): # field set to "application/x-www-form-urlencoded". elif self.signature_type == SIGNATURE_TYPE_BODY and not ( should_have_params and has_params and not multipart): - raise ValueError('Body signatures may only be used with form-urlencoded content') + 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 # with the clause that parameters from body should only be included @@ -290,11 +300,12 @@ class Client(object): request.oauth_params = self.get_oauth_params(request) # generate the signature - request.oauth_params.append(('oauth_signature', self.get_oauth_signature(request))) + request.oauth_params.append( + ('oauth_signature', self.get_oauth_signature(request))) # render the signed request and return it uri, headers, body = self._render(request, formencode=True, - realm=(realm or self.realm)) + realm=(realm or self.realm)) if self.decoding: log.debug('Encoding URI, headers and body to %s.', self.decoding) diff --git a/oauthlib/oauth1/rfc5849/endpoints/access_token.py b/oauthlib/oauth1/rfc5849/endpoints/access_token.py index f3139fb..26db919 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/access_token.py +++ b/oauthlib/oauth1/rfc5849/endpoints/access_token.py @@ -21,6 +21,7 @@ log = logging.getLogger(__name__) class AccessTokenEndpoint(BaseEndpoint): + """An endpoint responsible for providing OAuth 1 access tokens. Typical use is to instantiate with a request validator and invoke the @@ -40,7 +41,7 @@ class AccessTokenEndpoint(BaseEndpoint): :returns: The token as an urlencoded string. """ request.realms = self.request_validator.get_realms( - request.resource_owner_key, request) + request.resource_owner_key, request) token = { 'oauth_token': self.token_generator(), 'oauth_token_secret': self.token_generator(), @@ -52,8 +53,7 @@ class AccessTokenEndpoint(BaseEndpoint): return urlencode(token.items()) def create_access_token_response(self, uri, http_method='GET', body=None, - headers=None, credentials=None): - + headers=None, credentials=None): """Create an access token response, with a new request token if valid. :param uri: The full URI of the token request. @@ -104,13 +104,13 @@ class AccessTokenEndpoint(BaseEndpoint): try: request = self._create_request(uri, http_method, body, headers) valid, processed_request = self.validate_access_token_request( - request) + request) if valid: token = self.create_access_token(request, credentials or {}) self.request_validator.invalidate_request_token( - request.client_key, - request.resource_owner_key, - request) + request.client_key, + request.resource_owner_key, + request) return resp_headers, token, 200 else: return {}, None, 401 @@ -131,20 +131,20 @@ class AccessTokenEndpoint(BaseEndpoint): if not request.resource_owner_key: raise errors.InvalidRequestError( - description='Missing resource owner.') + description='Missing resource owner.') if not self.request_validator.check_request_token( request.resource_owner_key): raise errors.InvalidRequestError( - description='Invalid resource owner key format.') + description='Invalid resource owner key format.') if not request.verifier: raise errors.InvalidRequestError( - description='Missing verifier.') + description='Missing verifier.') if not self.request_validator.check_verifier(request.verifier): raise errors.InvalidRequestError( - description='Invalid verifier format.') + description='Invalid verifier format.') if not self.request_validator.validate_timestamp_and_nonce( request.client_key, request.timestamp, request.nonce, request, @@ -159,7 +159,7 @@ class AccessTokenEndpoint(BaseEndpoint): # # Note that early exit would enable client enumeration valid_client = self.request_validator.validate_client_key( - request.client_key, request) + request.client_key, request) if not valid_client: request.client_key = self.request_validator.dummy_client @@ -185,10 +185,10 @@ class AccessTokenEndpoint(BaseEndpoint): # Note that early exit would enable resource owner authorization # verifier enumertion. valid_verifier = self.request_validator.validate_verifier( - request.client_key, - request.resource_owner_key, - request.verifier, - request) + request.client_key, + request.resource_owner_key, + request.verifier, + request) valid_signature = self._check_signature(request, is_token_request=True) diff --git a/oauthlib/oauth1/rfc5849/endpoints/authorization.py b/oauthlib/oauth1/rfc5849/endpoints/authorization.py index 7ebbfe8..a93a517 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/authorization.py +++ b/oauthlib/oauth1/rfc5849/endpoints/authorization.py @@ -17,7 +17,9 @@ try: except ImportError: from urllib.parse import urlencode + class AuthorizationEndpoint(BaseEndpoint): + """An endpoint responsible for letting authenticated users authorize access to their protected resources to a client. @@ -49,11 +51,11 @@ class AuthorizationEndpoint(BaseEndpoint): } verifier.update(credentials) self.request_validator.save_verifier( - request.resource_owner_key, verifier, request) + request.resource_owner_key, verifier, request) return verifier def create_authorization_response(self, uri, http_method='GET', body=None, - headers=None, realms=None, credentials=None): + headers=None, realms=None, credentials=None): """Create an authorization response, with a new request token if valid. :param uri: The full URI of the token request. @@ -105,11 +107,11 @@ class AuthorizationEndpoint(BaseEndpoint): 200 """ request = self._create_request(uri, http_method=http_method, body=body, - headers=headers) + headers=headers) if not request.resource_owner_key: raise errors.InvalidRequestError( - 'Missing mandatory parameter oauth_token.') + 'Missing mandatory parameter oauth_token.') if not self.request_validator.verify_request_token( request.resource_owner_key, request): raise errors.InvalidClientError() @@ -118,22 +120,24 @@ class AuthorizationEndpoint(BaseEndpoint): if (request.realms and not self.request_validator.verify_realms( request.resource_owner_key, request.realms, request)): raise errors.InvalidRequestError( - description=('User granted access to realms outside of ' - 'what the client may request.')) + description=('User granted access to realms outside of ' + 'what the client may request.')) verifier = self.create_verifier(request, credentials or {}) redirect_uri = self.request_validator.get_redirect_uri( - request.resource_owner_key, request) + request.resource_owner_key, request) if redirect_uri == 'oob': - response_headers = {'Content-Type': 'application/x-www-form-urlencoded'} + response_headers = { + 'Content-Type': 'application/x-www-form-urlencoded'} response_body = urlencode(verifier) return response_headers, response_body, 200 else: - populated_redirect = add_params_to_uri(redirect_uri, verifier.items()) + populated_redirect = add_params_to_uri( + redirect_uri, verifier.items()) return {'Location': populated_redirect}, None, 302 def get_realms_and_credentials(self, uri, http_method='GET', body=None, - headers=None): + headers=None): """Fetch realms and credentials for the presented request token. :param uri: The full URI of the token request. @@ -146,12 +150,12 @@ class AuthorizationEndpoint(BaseEndpoint): authorization form. """ request = self._create_request(uri, http_method=http_method, body=body, - headers=headers) + headers=headers) if not self.request_validator.verify_request_token( request.resource_owner_key, request): raise errors.InvalidClientError() realms = self.request_validator.get_realms( - request.resource_owner_key, request) + request.resource_owner_key, request) return realms, {'resource_owner_key': request.resource_owner_key} diff --git a/oauthlib/oauth1/rfc5849/endpoints/base.py b/oauthlib/oauth1/rfc5849/endpoints/base.py index 4db2f07..42006a1 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/base.py +++ b/oauthlib/oauth1/rfc5849/endpoints/base.py @@ -30,13 +30,14 @@ class BaseEndpoint(object): """Extracts parameters from query, headers and body. Signature type is set to the source in which parameters were found. """ - # Per RFC5849, only the Authorization header may contain the 'realm' optional parameter. + # Per RFC5849, only the Authorization header may contain the 'realm' + # optional parameter. header_params = signature.collect_parameters(headers=request.headers, - exclude_oauth_signature=False, with_realm=True) + exclude_oauth_signature=False, with_realm=True) body_params = signature.collect_parameters(body=request.body, - exclude_oauth_signature=False) + exclude_oauth_signature=False) query_params = signature.collect_parameters(uri_query=request.uri_query, - exclude_oauth_signature=False) + exclude_oauth_signature=False) params = [] params.extend(header_params) @@ -54,15 +55,16 @@ class BaseEndpoint(object): if len(signature_types_with_oauth_params) > 1: found_types = [s[0] for s in signature_types_with_oauth_params] raise errors.InvalidRequestError( - description=('oauth_ params must come from only 1 signature' - 'type but were found in %s', - ', '.join(found_types))) + description=('oauth_ params must come from only 1 signature' + 'type but were found in %s', + ', '.join(found_types))) try: - signature_type, params, oauth_params = signature_types_with_oauth_params[0] + signature_type, params, oauth_params = signature_types_with_oauth_params[ + 0] except IndexError: raise errors.InvalidRequestError( - description='Missing mandatory OAuth parameters.') + description='Missing mandatory OAuth parameters.') return signature_type, params, oauth_params @@ -76,13 +78,13 @@ class BaseEndpoint(object): request = Request(uri, http_method, '', headers) signature_type, params, oauth_params = ( - self._get_signature_type_and_params(request)) + self._get_signature_type_and_params(request)) # The server SHOULD return a 400 (Bad Request) status code when # receiving a request with duplicated protocol parameters. if len(dict(oauth_params)) != len(oauth_params): raise errors.InvalidRequestError( - description='Duplicate OAuth2 entries.') + description='Duplicate OAuth2 entries.') oauth_params = dict(oauth_params) request.signature = oauth_params.get('oauth_signature') @@ -101,7 +103,8 @@ class BaseEndpoint(object): request.params = [(k, v) for k, v in params if k != "oauth_signature"] if 'realm' in request.headers.get('Authorization', ''): - request.params = [(k, v) for k, v in request.params if k != "realm"] + request.params = [(k, v) + for k, v in request.params if k != "realm"] return request @@ -118,7 +121,7 @@ class BaseEndpoint(object): request.nonce, request.timestamp, request.signature_method)): raise errors.InvalidRequestError( - description='Missing mandatory OAuth parameters.') + description='Missing mandatory OAuth parameters.') # OAuth does not mandate a particular signature method, as each # implementation can have its own unique requirements. Servers are @@ -131,31 +134,31 @@ class BaseEndpoint(object): if (not request.signature_method in self.request_validator.allowed_signature_methods): raise errors.InvalidSignatureMethodError( - description="Invalid signature, %s not in %r." % ( - request.signature_method, - self.request_validator.allowed_signature_methods)) + description="Invalid signature, %s not in %r." % ( + request.signature_method, + self.request_validator.allowed_signature_methods)) # Servers receiving an authenticated request MUST validate it by: # If the "oauth_version" parameter is present, ensuring its value is # "1.0". if ('oauth_version' in request.oauth_params and - request.oauth_params['oauth_version'] != '1.0'): + request.oauth_params['oauth_version'] != '1.0'): raise errors.InvalidRequestError( - description='Invalid OAuth version.') + description='Invalid OAuth version.') # The timestamp value MUST be a positive integer. Unless otherwise # specified by the server's documentation, the timestamp is expressed # in the number of seconds since January 1, 1970 00:00:00 GMT. if len(request.timestamp) != 10: raise errors.InvalidRequestError( - description='Invalid timestamp size') + description='Invalid timestamp size') try: ts = int(request.timestamp) except ValueError: raise errors.InvalidRequestError( - description='Timestamp must be an integer.') + description='Timestamp must be an integer.') else: # To avoid the need to retain an infinite number of nonce values for @@ -163,19 +166,19 @@ class BaseEndpoint(object): # which a request with an old timestamp is rejected. if abs(time.time() - ts) > self.request_validator.timestamp_lifetime: raise errors.InvalidRequestError( - description=('Timestamp given is invalid, differ from ' - 'allowed by over %s seconds.' % ( - self.request_validator.timestamp_lifetime))) + description=('Timestamp given is invalid, differ from ' + 'allowed by over %s seconds.' % ( + self.request_validator.timestamp_lifetime))) # Provider specific validation of parameters, used to enforce # restrictions such as character set and length. if not self.request_validator.check_client_key(request.client_key): raise errors.InvalidRequestError( - description='Invalid client key format.') + description='Invalid client key format.') if not self.request_validator.check_nonce(request.nonce): raise errors.InvalidRequestError( - description='Invalid nonce format.') + description='Invalid nonce format.') def _check_signature(self, request, is_token_request=False): # ---- RSA Signature verification ---- @@ -183,7 +186,7 @@ class BaseEndpoint(object): # 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 rsa_key = self.request_validator.get_rsa_key( - request.client_key, request) + request.client_key, request) valid_signature = signature.verify_rsa_sha1(request, rsa_key) # ---- HMAC or Plaintext Signature verification ---- @@ -194,7 +197,7 @@ class BaseEndpoint(object): # client via the "oauth_signature" parameter. # .. _`Section 3.4`: http://tools.ietf.org/html/rfc5849#section-3.4 client_secret = self.request_validator.get_client_secret( - request.client_key, request) + request.client_key, request) resource_owner_secret = None if request.resource_owner_key: if is_token_request: @@ -206,8 +209,8 @@ class BaseEndpoint(object): if request.signature_method == SIGNATURE_HMAC: valid_signature = signature.verify_hmac_sha1(request, - client_secret, resource_owner_secret) + client_secret, resource_owner_secret) else: valid_signature = signature.verify_plaintext(request, - client_secret, resource_owner_secret) + client_secret, resource_owner_secret) return valid_signature diff --git a/oauthlib/oauth1/rfc5849/endpoints/pre_configured.py b/oauthlib/oauth1/rfc5849/endpoints/pre_configured.py index ceb8dac..f0705a8 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/pre_configured.py +++ b/oauthlib/oauth1/rfc5849/endpoints/pre_configured.py @@ -5,7 +5,7 @@ from . import AccessTokenEndpoint, ResourceEndpoint class WebApplicationServer(RequestTokenEndpoint, AuthorizationEndpoint, - AccessTokenEndpoint, ResourceEndpoint): + AccessTokenEndpoint, ResourceEndpoint): def __init__(self, request_validator): RequestTokenEndpoint.__init__(self, request_validator) diff --git a/oauthlib/oauth1/rfc5849/endpoints/request_token.py b/oauthlib/oauth1/rfc5849/endpoints/request_token.py index 9424b9d..e97c34b 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/request_token.py +++ b/oauthlib/oauth1/rfc5849/endpoints/request_token.py @@ -21,6 +21,7 @@ log = logging.getLogger(__name__) class RequestTokenEndpoint(BaseEndpoint): + """An endpoint responsible for providing OAuth 1 request tokens. Typical use is to instantiate with a request validator and invoke the @@ -47,7 +48,7 @@ class RequestTokenEndpoint(BaseEndpoint): return urlencode(token.items()) def create_request_token_response(self, uri, http_method='GET', body=None, - headers=None, credentials=None): + headers=None, credentials=None): """Create a request token response, with a new request token if valid. :param uri: The full URI of the token request. @@ -98,7 +99,7 @@ class RequestTokenEndpoint(BaseEndpoint): try: request = self._create_request(uri, http_method, body, headers) valid, processed_request = self.validate_request_token_request( - request) + request) if valid: token = self.create_request_token(request, credentials or {}) return resp_headers, token, 200 @@ -123,15 +124,15 @@ class RequestTokenEndpoint(BaseEndpoint): request.realms = request.realm.split(' ') else: request.realms = self.request_validator.get_default_realms( - request.client_key, request) + request.client_key, request) if not self.request_validator.check_realms(request.realms): raise errors.InvalidRequestError( - description='Invalid realm %s. Allowed are %r.' % ( - request.realms, self.request_validator.realms)) + description='Invalid realm %s. Allowed are %r.' % ( + request.realms, self.request_validator.realms)) if not request.redirect_uri: raise errors.InvalidRequestError( - description='Missing callback URI.') + description='Missing callback URI.') if not self.request_validator.validate_timestamp_and_nonce( request.client_key, request.timestamp, request.nonce, request, @@ -146,7 +147,7 @@ class RequestTokenEndpoint(BaseEndpoint): # # Note that early exit would enable client enumeration valid_client = self.request_validator.validate_client_key( - request.client_key, request) + request.client_key, request) if not valid_client: request.client_key = self.request_validator.dummy_client @@ -173,13 +174,13 @@ class RequestTokenEndpoint(BaseEndpoint): # that the realm is now tied to the access token and not provided by # the client. valid_realm = self.request_validator.validate_requested_realms( - request.client_key, request.realms, request) + request.client_key, request.realms, request) # 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 valid_redirect = self.request_validator.validate_redirect_uri( - request.client_key, request.redirect_uri, request) + request.client_key, request.redirect_uri, request) if not request.redirect_uri: raise NotImplementedError('Redirect URI must either be provided ' 'or set to a default during validation.') diff --git a/oauthlib/oauth1/rfc5849/endpoints/resource.py b/oauthlib/oauth1/rfc5849/endpoints/resource.py index 00b5c5f..651a87c 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/resource.py +++ b/oauthlib/oauth1/rfc5849/endpoints/resource.py @@ -17,6 +17,7 @@ log = logging.getLogger(__name__) class ResourceEndpoint(BaseEndpoint): + """An endpoint responsible for protecting resources. Typical use is to instantiate with a request validator and invoke the @@ -52,7 +53,7 @@ class ResourceEndpoint(BaseEndpoint): """ def validate_protected_resource_request(self, uri, http_method='GET', - body=None, headers=None, realms=None): + body=None, headers=None, realms=None): """Create a request token response, with a new request token if valid. :param uri: The full URI of the token request. @@ -97,7 +98,7 @@ class ResourceEndpoint(BaseEndpoint): # # Note that early exit would enable client enumeration valid_client = self.request_validator.validate_client_key( - request.client_key, request) + request.client_key, request) if not valid_client: request.client_key = self.request_validator.dummy_client @@ -136,8 +137,8 @@ class ResourceEndpoint(BaseEndpoint): # that the realm is now tied to the access token and not provided by # the client. valid_realm = self.request_validator.validate_realms(request.client_key, - request.resource_owner_key, request, uri=request.uri, - realms=realms) + request.resource_owner_key, request, uri=request.uri, + realms=realms) valid_signature = self._check_signature(request) diff --git a/oauthlib/oauth1/rfc5849/endpoints/signature_only.py b/oauthlib/oauth1/rfc5849/endpoints/signature_only.py index 0cdcdd3..2f8e7c9 100644 --- a/oauthlib/oauth1/rfc5849/endpoints/signature_only.py +++ b/oauthlib/oauth1/rfc5849/endpoints/signature_only.py @@ -17,10 +17,11 @@ log = logging.getLogger(__name__) class SignatureOnlyEndpoint(BaseEndpoint): + """An endpoint only responsible for verifying an oauth signature.""" def validate_request(self, uri, http_method='GET', - body=None, headers=None): + body=None, headers=None): """Validate a signed OAuth request. :param uri: The full URI of the token request. @@ -54,7 +55,7 @@ class SignatureOnlyEndpoint(BaseEndpoint): # # Note that early exit would enable client enumeration valid_client = self.request_validator.validate_client_key( - request.client_key, request) + request.client_key, request) if not valid_client: request.client_key = self.request_validator.dummy_client diff --git a/oauthlib/oauth1/rfc5849/parameters.py b/oauthlib/oauth1/rfc5849/parameters.py index dee22a2..f0963ab 100644 --- a/oauthlib/oauth1/rfc5849/parameters.py +++ b/oauthlib/oauth1/rfc5849/parameters.py @@ -77,7 +77,7 @@ def prepare_headers(oauth_params, headers=None, realm=None): if realm: # NOTE: realm should *not* be escaped authorization_header_parameters = ('realm="%s", ' % realm + - authorization_header_parameters) + authorization_header_parameters) # the auth-scheme name set to "OAuth" (case insensitive). authorization_header = 'OAuth %s' % authorization_header_parameters @@ -132,5 +132,6 @@ def prepare_request_uri_query(oauth_params, uri): """ # append OAuth params to the existing set of query components sch, net, path, par, query, fra = urlparse(uri) - query = urlencode(_append_params(oauth_params, extract_params(query) or [])) + query = urlencode( + _append_params(oauth_params, extract_params(query) or [])) return urlunparse((sch, net, path, par, query, fra)) diff --git a/oauthlib/oauth1/rfc5849/request_validator.py b/oauthlib/oauth1/rfc5849/request_validator.py index ef4cc92..e722029 100644 --- a/oauthlib/oauth1/rfc5849/request_validator.py +++ b/oauthlib/oauth1/rfc5849/request_validator.py @@ -12,6 +12,7 @@ from . import SIGNATURE_METHODS, utils class RequestValidator(object): + """A validator/datastore interaction base class for OAuth 1 providers. OAuth providers should inherit from RequestValidator and implement the @@ -552,7 +553,7 @@ class RequestValidator(object): raise NotImplementedError("Subclasses must implement this function.") def validate_timestamp_and_nonce(self, client_key, timestamp, nonce, - request, request_token=None, access_token=None): + request, request_token=None, access_token=None): """Validates that the nonce has not been used before. :param client_key: The client/consumer key. @@ -653,7 +654,7 @@ class RequestValidator(object): raise NotImplementedError("Subclasses must implement this function.") def validate_realms(self, client_key, token, request, uri=None, - realms=None): + realms=None): """Validates access to the request realm. :param client_key: The client/consumer key. diff --git a/oauthlib/oauth1/rfc5849/signature.py b/oauthlib/oauth1/rfc5849/signature.py index 58a3497..b3a419c 100644 --- a/oauthlib/oauth1/rfc5849/signature.py +++ b/oauthlib/oauth1/rfc5849/signature.py @@ -36,7 +36,7 @@ from oauthlib.common import bytes_type, unicode_type def construct_base_string(http_method, base_string_uri, - normalized_encoded_request_parameters): + normalized_encoded_request_parameters): """**String Construction** Per `section 3.4.1.1`_ of the spec. @@ -185,10 +185,10 @@ def normalize_base_string_uri(uri, host=None): # particular manner that is often different from their original # encoding scheme, and concatenated into a single string. # -# .. _`section 3.4.1.3`: http://tools.ietf.org/html/rfc5849#section-3.4.1.3 +# .. _`section 3.4.1.3`: http://tools.ietf.org/html/rfc5849#section-3.4.1.3 def collect_parameters(uri_query='', body=[], headers=None, - exclude_oauth_signature=True, with_realm=False): + exclude_oauth_signature=True, with_realm=False): """**Parameter Sources** Parameters starting with `oauth_` will be unescaped. @@ -305,7 +305,7 @@ def collect_parameters(uri_query='', body=[], headers=None, # base string if present. if exclude_oauth_signature: unescaped_params = list(filter(lambda i: i[0] != 'oauth_signature', - unescaped_params)) + unescaped_params)) return unescaped_params @@ -409,10 +409,11 @@ def normalize_parameters(params): def sign_hmac_sha1_with_client(base_string, client): - return sign_hmac_sha1(base_string, - client.client_secret, - client.resource_owner_secret - ) + return sign_hmac_sha1(base_string, + client.client_secret, + client.resource_owner_secret + ) + def sign_hmac_sha1(base_string, client_secret, resource_owner_secret): """**HMAC-SHA1** @@ -536,8 +537,9 @@ def sign_plaintext(client_secret, resource_owner_secret): def sign_plaintext_with_client(base_string, client): return sign_plaintext(client.client_secret, client.resource_owner_secret) + def verify_hmac_sha1(request, client_secret=None, - resource_owner_secret=None): + resource_owner_secret=None): """Verify a HMAC-SHA1 signature. Per `section 3.4`_ of the spec. @@ -557,7 +559,7 @@ def verify_hmac_sha1(request, client_secret=None, uri = normalize_base_string_uri(request.uri) base_string = construct_base_string(request.http_method, uri, norm_params) signature = sign_hmac_sha1(base_string, client_secret, - resource_owner_secret) + resource_owner_secret) return safe_string_equals(signature, request.signature) diff --git a/oauthlib/oauth2/rfc6749/__init__.py b/oauthlib/oauth2/rfc6749/__init__.py index 05a7601..aff0ed8 100644 --- a/oauthlib/oauth2/rfc6749/__init__.py +++ b/oauthlib/oauth2/rfc6749/__init__.py @@ -19,6 +19,7 @@ log = logging.getLogger(__name__) class BaseEndpoint(object): + def __init__(self): self._available = True self._catch_errors = False @@ -57,7 +58,8 @@ def catch_errors_and_unavailability(f): raise except Exception as e: error = ServerError() - log.warning('Exception caught while processing request, %s.' % e) + log.warning( + 'Exception caught while processing request, %s.' % e) return {}, error.json, 500 else: return f(endpoint, uri, *args, **kwargs) diff --git a/oauthlib/oauth2/rfc6749/clients/backend_application.py b/oauthlib/oauth2/rfc6749/clients/backend_application.py index 3516ee3..9e0d438 100644 --- a/oauthlib/oauth2/rfc6749/clients/backend_application.py +++ b/oauthlib/oauth2/rfc6749/clients/backend_application.py @@ -14,6 +14,7 @@ from ..parameters import parse_token_response class BackendApplicationClient(Client): + """A public client utilizing the client credentials grant workflow. The client can request an access token using only its client diff --git a/oauthlib/oauth2/rfc6749/clients/base.py b/oauthlib/oauth2/rfc6749/clients/base.py index 9bc9a1a..da9f26c 100644 --- a/oauthlib/oauth2/rfc6749/clients/base.py +++ b/oauthlib/oauth2/rfc6749/clients/base.py @@ -23,6 +23,7 @@ BODY = 'body' class Client(object): + """Base OAuth2 client responsible for access tokens. While this class can be used to simply append tokens onto requests @@ -30,14 +31,14 @@ class Client(object): """ def __init__(self, client_id, - default_token_placement=AUTH_HEADER, - token_type='Bearer', - access_token=None, - refresh_token=None, - mac_key=None, - mac_algorithm=None, - token=None, - **kwargs): + default_token_placement=AUTH_HEADER, + token_type='Bearer', + access_token=None, + refresh_token=None, + mac_key=None, + mac_algorithm=None, + token=None, + **kwargs): """Initialize a client with commonly used attributes.""" self.client_id = client_id @@ -68,7 +69,7 @@ class Client(object): } def add_token(self, uri, http_method='GET', body=None, headers=None, - token_placement=None, **kwargs): + token_placement=None, **kwargs): """Add token to the request uri, body or authorization header. The access token type provides the client with the information @@ -107,7 +108,8 @@ class Client(object): token_placement = token_placement or self.default_token_placement - case_insensitive_token_types = dict((k.lower(), v) for k, v in self.token_types.items()) + case_insensitive_token_types = dict( + (k.lower(), v) for k, v in self.token_types.items()) if not self.token_type.lower() in case_insensitive_token_types: raise ValueError("Unsupported token type: %s" % self.token_type) @@ -118,7 +120,7 @@ class Client(object): raise TokenExpiredError() return case_insensitive_token_types[self.token_type.lower()](uri, http_method, body, - headers, token_placement, **kwargs) + headers, token_placement, **kwargs) def prepare_refresh_body(self, body='', refresh_token=None, scope=None, **kwargs): """Prepare an access token request, using a refresh token. @@ -141,10 +143,10 @@ class Client(object): """ refresh_token = refresh_token or self.refresh_token return prepare_token_request('refresh_token', body=body, scope=scope, - refresh_token=refresh_token, **kwargs) + refresh_token=refresh_token, **kwargs) def _add_bearer_token(self, uri, http_method='GET', body=None, - headers=None, token_placement=None): + headers=None, token_placement=None): """Add a bearer token to the request uri, body or authorization header.""" if token_placement == AUTH_HEADER: headers = tokens.prepare_bearer_headers(self.access_token, headers) @@ -160,14 +162,14 @@ class Client(object): return uri, headers, body def _add_mac_token(self, uri, http_method='GET', body=None, - headers=None, token_placement=AUTH_HEADER, ext=None, **kwargs): + headers=None, token_placement=AUTH_HEADER, ext=None, **kwargs): """Add a MAC token to the request authorization header. Warning: MAC token support is experimental as the spec is not yet stable. """ headers = tokens.prepare_mac_header(self.access_token, uri, - self.mac_key, http_method, headers=headers, body=body, ext=ext, - hash_algorithm=self.mac_algorithm, **kwargs) + self.mac_key, http_method, headers=headers, body=body, ext=ext, + hash_algorithm=self.mac_algorithm, **kwargs) return uri, headers, body def _populate_attributes(self, response): diff --git a/oauthlib/oauth2/rfc6749/clients/legacy_application.py b/oauthlib/oauth2/rfc6749/clients/legacy_application.py index 1e1e32f..edb68d7 100644 --- a/oauthlib/oauth2/rfc6749/clients/legacy_application.py +++ b/oauthlib/oauth2/rfc6749/clients/legacy_application.py @@ -14,6 +14,7 @@ from ..parameters import parse_token_response class LegacyApplicationClient(Client): + """A public client using the resource owner password and username directly. The resource owner password credentials grant type is suitable in @@ -69,7 +70,7 @@ class LegacyApplicationClient(Client): .. _`Section 3.2.1`: http://tools.ietf.org/html/rfc6749#section-3.2.1 """ return prepare_token_request('password', body=body, username=username, - password=password, scope=scope, **kwargs) + password=password, scope=scope, **kwargs) def parse_request_body_response(self, body, scope=None): """Parse the JSON response body. diff --git a/oauthlib/oauth2/rfc6749/clients/mobile_application.py b/oauthlib/oauth2/rfc6749/clients/mobile_application.py index c173f9b..6b79c81 100644 --- a/oauthlib/oauth2/rfc6749/clients/mobile_application.py +++ b/oauthlib/oauth2/rfc6749/clients/mobile_application.py @@ -14,6 +14,7 @@ from ..parameters import parse_implicit_response class MobileApplicationClient(Client): + """A public client utilizing the implicit code grant workflow. A user-agent-based application is a public client in which the @@ -47,7 +48,7 @@ class MobileApplicationClient(Client): """ def prepare_request_uri(self, uri, redirect_uri=None, scope=None, - state=None, **kwargs): + state=None, **kwargs): """Prepare the implicit grant request URI. The client constructs the request URI by adding the following @@ -92,7 +93,7 @@ class MobileApplicationClient(Client): .. _`Section 10.12`: http://tools.ietf.org/html/rfc6749#section-10.12 """ return prepare_grant_uri(uri, self.client_id, 'token', - redirect_uri=redirect_uri, state=state, scope=scope, **kwargs) + redirect_uri=redirect_uri, state=state, scope=scope, **kwargs) def parse_request_uri_response(self, uri, state=None, scope=None): """Parse the response URI fragment. diff --git a/oauthlib/oauth2/rfc6749/clients/web_application.py b/oauthlib/oauth2/rfc6749/clients/web_application.py index 6af9f88..6aeb831 100644 --- a/oauthlib/oauth2/rfc6749/clients/web_application.py +++ b/oauthlib/oauth2/rfc6749/clients/web_application.py @@ -15,6 +15,7 @@ from ..parameters import parse_token_response class WebApplicationClient(Client): + """A client utilizing the authorization code grant workflow. A web application is a confidential client running on a web @@ -37,7 +38,7 @@ class WebApplicationClient(Client): self.code = code def prepare_request_uri(self, uri, redirect_uri=None, scope=None, - state=None, **kwargs): + state=None, **kwargs): """Prepare the authorization code request URI The client constructs the request URI by adding the following @@ -82,10 +83,10 @@ class WebApplicationClient(Client): .. _`Section 10.12`: http://tools.ietf.org/html/rfc6749#section-10.12 """ return prepare_grant_uri(uri, self.client_id, 'code', - redirect_uri=redirect_uri, scope=scope, state=state, **kwargs) + redirect_uri=redirect_uri, scope=scope, state=state, **kwargs) def prepare_request_body(self, client_id=None, code=None, body='', - redirect_uri=None, **kwargs): + redirect_uri=None, **kwargs): """Prepare the access token request body. The client makes a request to the token endpoint by adding the @@ -124,7 +125,7 @@ class WebApplicationClient(Client): """ code = code or self.code return prepare_token_request('authorization_code', code=code, body=body, - client_id=self.client_id, redirect_uri=redirect_uri, **kwargs) + client_id=self.client_id, redirect_uri=redirect_uri, **kwargs) def parse_request_uri_response(self, uri, state=None): """Parse the URI query for code and state. diff --git a/oauthlib/oauth2/rfc6749/endpoints/authorization.py b/oauthlib/oauth2/rfc6749/endpoints/authorization.py index 4244a88..ada24d7 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/authorization.py +++ b/oauthlib/oauth2/rfc6749/endpoints/authorization.py @@ -18,6 +18,7 @@ log = logging.getLogger(__name__) class AuthorizationEndpoint(BaseEndpoint): + """Authorization endpoint - used by the client to obtain authorization from the resource owner via user-agent redirection. @@ -61,7 +62,7 @@ class AuthorizationEndpoint(BaseEndpoint): """ def __init__(self, default_response_type, default_token_type, - response_types): + response_types): BaseEndpoint.__init__(self) self._response_types = response_types self._default_response_type = default_response_type @@ -85,27 +86,29 @@ class AuthorizationEndpoint(BaseEndpoint): @catch_errors_and_unavailability def create_authorization_response(self, uri, http_method='GET', body=None, - headers=None, scopes=None, credentials=None): + headers=None, scopes=None, credentials=None): """Extract response_type and route to the designated handler.""" - request = Request(uri, http_method=http_method, body=body, headers=headers) + request = Request( + uri, http_method=http_method, body=body, headers=headers) request.scopes = scopes # TODO: decide whether this should be a required argument request.user = None # TODO: explain this in docs for k, v in (credentials or {}).items(): setattr(request, k, v) response_type_handler = self.response_types.get( - request.response_type, self.default_response_type_handler) + request.response_type, self.default_response_type_handler) log.debug('Dispatching response_type %s request to %r.', request.response_type, response_type_handler) return response_type_handler.create_authorization_response( - request, self.default_token_type) + request, self.default_token_type) @catch_errors_and_unavailability def validate_authorization_request(self, uri, http_method='GET', body=None, - headers=None): + headers=None): """Extract response_type and route to the designated handler.""" - request = Request(uri, http_method=http_method, body=body, headers=headers) + request = Request( + uri, http_method=http_method, body=body, headers=headers) request.scopes = None response_type_handler = self.response_types.get( - request.response_type, self.default_response_type_handler) + request.response_type, self.default_response_type_handler) return response_type_handler.validate_authorization_request(request) diff --git a/oauthlib/oauth2/rfc6749/endpoints/base.py b/oauthlib/oauth2/rfc6749/endpoints/base.py index 24f00d9..759c6c8 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/base.py +++ b/oauthlib/oauth2/rfc6749/endpoints/base.py @@ -18,6 +18,7 @@ log = logging.getLogger(__name__) class BaseEndpoint(object): + def __init__(self): self._available = True self._catch_errors = False @@ -56,7 +57,8 @@ def catch_errors_and_unavailability(f): raise except Exception as e: error = ServerError() - log.warning('Exception caught while processing request, %s.' % e) + log.warning( + 'Exception caught while processing request, %s.' % e) return {}, error.json, 500 else: return f(endpoint, uri, *args, **kwargs) diff --git a/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py b/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py index 00fe696..21ed2dd 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py +++ b/oauthlib/oauth2/rfc6749/endpoints/pre_configured.py @@ -22,7 +22,8 @@ from .revocation import RevocationEndpoint class Server(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): + RevocationEndpoint): + """An all-in-one endpoint featuring all four major grant types.""" def __init__(self, request_validator, token_expires_in=None, @@ -43,36 +44,38 @@ class Server(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint, """ auth_grant = AuthorizationCodeGrant(request_validator) implicit_grant = ImplicitGrant(request_validator) - password_grant = ResourceOwnerPasswordCredentialsGrant(request_validator) + password_grant = ResourceOwnerPasswordCredentialsGrant( + request_validator) credentials_grant = ClientCredentialsGrant(request_validator) refresh_grant = RefreshTokenGrant(request_validator) bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) AuthorizationEndpoint.__init__(self, default_response_type='code', - response_types={ - 'code': auth_grant, - 'token': implicit_grant, - }, - default_token_type=bearer) + response_types={ + 'code': auth_grant, + 'token': implicit_grant, + }, + default_token_type=bearer) TokenEndpoint.__init__(self, default_grant_type='authorization_code', - grant_types={ - 'authorization_code': auth_grant, - 'password': password_grant, - 'client_credentials': credentials_grant, - 'refresh_token': refresh_grant, - }, - default_token_type=bearer) + grant_types={ + 'authorization_code': auth_grant, + 'password': password_grant, + 'client_credentials': credentials_grant, + 'refresh_token': refresh_grant, + }, + default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', - token_types={'Bearer': bearer}) + token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator) class WebApplicationServer(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): + RevocationEndpoint): + """An all-in-one endpoint featuring Authorization code grant and Bearer tokens.""" def __init__(self, request_validator, token_generator=None, - token_expires_in=None, refresh_token_generator=None, **kwargs): + token_expires_in=None, refresh_token_generator=None, **kwargs): """Construct a new web application server. :param request_validator: An implementation of @@ -91,25 +94,26 @@ class WebApplicationServer(AuthorizationEndpoint, TokenEndpoint, ResourceEndpoin bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) AuthorizationEndpoint.__init__(self, default_response_type='code', - response_types={'code': auth_grant}, - default_token_type=bearer) + response_types={'code': auth_grant}, + default_token_type=bearer) TokenEndpoint.__init__(self, default_grant_type='authorization_code', - grant_types={ - 'authorization_code': auth_grant, - 'refresh_token': refresh_grant, - }, - default_token_type=bearer) + grant_types={ + 'authorization_code': auth_grant, + 'refresh_token': refresh_grant, + }, + default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', - token_types={'Bearer': bearer}) + token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator) class MobileApplicationServer(AuthorizationEndpoint, ResourceEndpoint, - RevocationEndpoint): + RevocationEndpoint): + """An all-in-one endpoint featuring Implicit code grant and Bearer tokens.""" def __init__(self, request_validator, token_generator=None, - token_expires_in=None, refresh_token_generator=None, **kwargs): + token_expires_in=None, refresh_token_generator=None, **kwargs): """Construct a new implicit grant server. :param request_validator: An implementation of @@ -127,20 +131,22 @@ class MobileApplicationServer(AuthorizationEndpoint, ResourceEndpoint, bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) AuthorizationEndpoint.__init__(self, default_response_type='token', - response_types={'token': implicit_grant}, - default_token_type=bearer) + response_types={ + 'token': implicit_grant}, + default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', - token_types={'Bearer': bearer}) + token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator, - supported_token_types=['access_token']) + supported_token_types=['access_token']) class LegacyApplicationServer(TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): + RevocationEndpoint): + """An all-in-one endpoint featuring Resource Owner Password Credentials grant and Bearer tokens.""" def __init__(self, request_validator, token_generator=None, - token_expires_in=None, refresh_token_generator=None, **kwargs): + token_expires_in=None, refresh_token_generator=None, **kwargs): """Construct a resource owner password credentials grant server. :param request_validator: An implementation of @@ -154,27 +160,29 @@ class LegacyApplicationServer(TokenEndpoint, ResourceEndpoint, :param kwargs: Extra parameters to pass to authorization-, token-, resource-, and revocation-endpoint constructors. """ - password_grant = ResourceOwnerPasswordCredentialsGrant(request_validator) + password_grant = ResourceOwnerPasswordCredentialsGrant( + request_validator) refresh_grant = RefreshTokenGrant(request_validator) bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) TokenEndpoint.__init__(self, default_grant_type='password', - grant_types={ - 'password': password_grant, - 'refresh_token': refresh_grant, - }, - default_token_type=bearer) + grant_types={ + 'password': password_grant, + 'refresh_token': refresh_grant, + }, + default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', - token_types={'Bearer': bearer}) + token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator) class BackendApplicationServer(TokenEndpoint, ResourceEndpoint, - RevocationEndpoint): + RevocationEndpoint): + """An all-in-one endpoint featuring Client Credentials grant and Bearer tokens.""" def __init__(self, request_validator, token_generator=None, - token_expires_in=None, refresh_token_generator=None, **kwargs): + token_expires_in=None, refresh_token_generator=None, **kwargs): """Construct a client credentials grant server. :param request_validator: An implementation of @@ -192,9 +200,10 @@ class BackendApplicationServer(TokenEndpoint, ResourceEndpoint, bearer = BearerToken(request_validator, token_generator, token_expires_in, refresh_token_generator) TokenEndpoint.__init__(self, default_grant_type='client_credentials', - grant_types={'client_credentials': credentials_grant}, - default_token_type=bearer) + grant_types={ + 'client_credentials': credentials_grant}, + default_token_type=bearer) ResourceEndpoint.__init__(self, default_token='Bearer', - token_types={'Bearer': bearer}) + token_types={'Bearer': bearer}) RevocationEndpoint.__init__(self, request_validator, - supported_token_types=['access_token']) + supported_token_types=['access_token']) diff --git a/oauthlib/oauth2/rfc6749/endpoints/resource.py b/oauthlib/oauth2/rfc6749/endpoints/resource.py index ee23d35..d03ed21 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/resource.py +++ b/oauthlib/oauth2/rfc6749/endpoints/resource.py @@ -18,6 +18,7 @@ log = logging.getLogger(__name__) class ResourceEndpoint(BaseEndpoint): + """Authorizes access to protected resources. The client accesses protected resources by presenting the access @@ -42,6 +43,7 @@ class ResourceEndpoint(BaseEndpoint): https://example.com/protected?access_token=kjfch2345sdf # Query access_token=sdf23409df # Body """ + def __init__(self, default_token, token_types): BaseEndpoint.__init__(self) self._tokens = token_types @@ -61,13 +63,13 @@ class ResourceEndpoint(BaseEndpoint): @catch_errors_and_unavailability def verify_request(self, uri, http_method='GET', body=None, headers=None, - scopes=None): + scopes=None): """Validate client, code etc, return body + headers""" request = Request(uri, http_method, body, headers) request.token_type = self.find_token_type(request) request.scopes = scopes token_type_handler = self.tokens.get(request.token_type, - self.default_token_type_handler) + self.default_token_type_handler) log.debug('Dispatching token_type %s request to %r.', request.token_type, token_type_handler) return token_type_handler.validate_request(request), request @@ -80,5 +82,6 @@ class ResourceEndpoint(BaseEndpoint): the most likely token type (if any) by asking each known token type to give an estimation based on the request. """ - estimates = sorted(((t.estimate_type(request), n) for n, t in self.tokens.items())) + estimates = sorted(((t.estimate_type(request), n) + for n, t in self.tokens.items())) return estimates[0][1] if len(estimates) else None diff --git a/oauthlib/oauth2/rfc6749/endpoints/revocation.py b/oauthlib/oauth2/rfc6749/endpoints/revocation.py index 45e8080..2e8e253 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/revocation.py +++ b/oauthlib/oauth2/rfc6749/endpoints/revocation.py @@ -21,6 +21,7 @@ log = logging.getLogger(__name__) class RevocationEndpoint(BaseEndpoint): + """Token revocation endpoint. Endpoint used by authenticated clients to revoke access and refresh tokens. @@ -37,11 +38,11 @@ class RevocationEndpoint(BaseEndpoint): BaseEndpoint.__init__(self) self.request_validator = request_validator self._supported_token_types = ( - supported_token_types or self.valid_token_types) + supported_token_types or self.valid_token_types) @catch_errors_and_unavailability def create_revocation_response(self, uri, http_method='POST', body=None, - headers=None): + headers=None): """Revoke supplied access or refresh token. @@ -60,7 +61,8 @@ class RevocationEndpoint(BaseEndpoint): An invalid token type hint value is ignored by the authorization server and does not influence the revocation response. """ - request = Request(uri, http_method=http_method, body=body, headers=headers) + request = Request( + uri, http_method=http_method, body=body, headers=headers) try: self.validate_revocation_request(request) log.debug('Token revocation valid for %r.', request) @@ -69,7 +71,7 @@ class RevocationEndpoint(BaseEndpoint): return {}, e.json, e.status_code self.request_validator.revoke_token(request.token, - request.token_type_hint, request) + request.token_type_hint, request) response_body = request.callback + '()' if request.callback else None return {}, response_body, 200 @@ -112,7 +114,7 @@ class RevocationEndpoint(BaseEndpoint): """ if not request.token: raise InvalidRequestError(request=request, - description='Missing token parameter.') + description='Missing token parameter.') if not self.request_validator.authenticate_client(request): raise InvalidClientError(request=request) diff --git a/oauthlib/oauth2/rfc6749/endpoints/token.py b/oauthlib/oauth2/rfc6749/endpoints/token.py index 267490f..cda56ad 100644 --- a/oauthlib/oauth2/rfc6749/endpoints/token.py +++ b/oauthlib/oauth2/rfc6749/endpoints/token.py @@ -19,6 +19,7 @@ log = logging.getLogger(__name__) class TokenEndpoint(BaseEndpoint): + """Token issuing endpoint. The token endpoint is used by the client to obtain an access token by @@ -85,14 +86,15 @@ class TokenEndpoint(BaseEndpoint): @catch_errors_and_unavailability def create_token_response(self, uri, http_method='GET', body=None, - headers=None, credentials=None): + headers=None, credentials=None): """Extract grant_type and route to the designated handler.""" - request = Request(uri, http_method=http_method, body=body, headers=headers) + request = Request( + uri, http_method=http_method, body=body, headers=headers) request.scopes = None request.extra_credentials = credentials grant_type_handler = self.grant_types.get(request.grant_type, - self.default_grant_type_handler) + self.default_grant_type_handler) log.debug('Dispatching grant_type %s request to %r.', request.grant_type, grant_type_handler) return grant_type_handler.create_token_response( - request, self.default_token_type) + request, self.default_token_type) diff --git a/oauthlib/oauth2/rfc6749/errors.py b/oauthlib/oauth2/rfc6749/errors.py index a015cb4..27f2477 100644 --- a/oauthlib/oauth2/rfc6749/errors.py +++ b/oauthlib/oauth2/rfc6749/errors.py @@ -106,6 +106,7 @@ class MissingTokenTypeError(OAuth2Error): class FatalClientError(OAuth2Error): + """Errors during authorization where user should not be redirected back. If the request fails due to a missing, invalid, or mismatching @@ -140,6 +141,7 @@ class InvalidClientIdError(FatalClientError): class InvalidRequestError(OAuth2Error): + """The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. @@ -148,12 +150,14 @@ class InvalidRequestError(OAuth2Error): class AccessDeniedError(OAuth2Error): + """The resource owner or authorization server denied the request.""" error = 'access_denied' status_code = 401 class UnsupportedResponseTypeError(OAuth2Error): + """The authorization server does not support obtaining an authorization code using this method. """ @@ -161,12 +165,14 @@ class UnsupportedResponseTypeError(OAuth2Error): class InvalidScopeError(OAuth2Error): + """The requested scope is invalid, unknown, or malformed.""" error = 'invalid_scope' status_code = 401 class ServerError(OAuth2Error): + """The authorization server encountered an unexpected condition that prevented it from fulfilling the request. (This error code is needed because a 500 Internal Server Error HTTP status code cannot be returned @@ -176,6 +182,7 @@ class ServerError(OAuth2Error): class TemporarilyUnavailableError(OAuth2Error): + """The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP @@ -185,6 +192,7 @@ class TemporarilyUnavailableError(OAuth2Error): class InvalidClientError(OAuth2Error): + """Client authentication failed (e.g. unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status @@ -200,6 +208,7 @@ class InvalidClientError(OAuth2Error): class InvalidGrantError(OAuth2Error): + """The provided authorization grant (e.g. authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was @@ -210,6 +219,7 @@ class InvalidGrantError(OAuth2Error): class UnauthorizedClientError(OAuth2Error): + """The authenticated client is not authorized to use this authorization grant type. """ @@ -218,6 +228,7 @@ class UnauthorizedClientError(OAuth2Error): class UnsupportedGrantTypeError(OAuth2Error): + """The authorization grant type is not supported by the authorization server. """ @@ -225,6 +236,7 @@ class UnsupportedGrantTypeError(OAuth2Error): class UnsupportedTokenTypeError(OAuth2Error): + """The authorization server does not support the revocation of the presented token type. I.e. the client tried to revoke an access token on a server not supporting this feature. @@ -240,6 +252,6 @@ def raise_from_error(error, params=None): 'uri': params.get('error_uri'), 'state': params.get('state') } - for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): + for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass): if cls.error == error: raise cls(**kwargs) diff --git a/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py b/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py index 65e9c65..05273e7 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py +++ b/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py @@ -19,6 +19,7 @@ log = logging.getLogger(__name__) class AuthorizationCodeGrant(GrantTypeBase): + """`Authorization Code Grant`_ The authorization code grant type is used to obtain both access @@ -93,6 +94,7 @@ class AuthorizationCodeGrant(GrantTypeBase): .. _`Authorization Code Grant`: http://tools.ietf.org/html/rfc6749#section-4.1 """ + def __init__(self, request_validator=None): self.request_validator = request_validator or RequestValidator() @@ -210,7 +212,8 @@ class AuthorizationCodeGrant(GrantTypeBase): grant = self.create_authorization_code(request) log.debug('Saving grant %r for %r.', grant, request) - self.request_validator.save_authorization_code(request.client_id, grant, request) + self.request_validator.save_authorization_code( + request.client_id, grant, request) return {'Location': common.add_params_to_uri(request.redirect_uri, grant.items())}, None, 302 def create_token_response(self, request, token_handler): @@ -223,9 +226,9 @@ class AuthorizationCodeGrant(GrantTypeBase): code is bound to the client identifier and redirection URI. """ headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store', + 'Pragma': 'no-cache', } try: self.validate_token_request(request) @@ -236,7 +239,7 @@ class AuthorizationCodeGrant(GrantTypeBase): token = token_handler.create_token(request, refresh_token=True) self.request_validator.invalidate_authorization_code( - request.client_id, request.code, request) + request.client_id, request.code, request) return headers, json.dumps(token), 200 def validate_authorization_request(self, request): @@ -264,10 +267,12 @@ class AuthorizationCodeGrant(GrantTypeBase): # REQUIRED. The client identifier as described in Section 2.2. # http://tools.ietf.org/html/rfc6749#section-2.2 if not request.client_id: - raise errors.MissingClientIdError(state=request.state, request=request) + raise errors.MissingClientIdError( + state=request.state, request=request) if not self.request_validator.validate_client_id(request.client_id, request): - raise errors.InvalidClientIdError(state=request.state, request=request) + raise errors.InvalidClientIdError( + state=request.state, request=request) # OPTIONAL. As described in Section 3.1.2. # http://tools.ietf.org/html/rfc6749#section-3.1.2 @@ -277,18 +282,21 @@ class AuthorizationCodeGrant(GrantTypeBase): 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(state=request.state, request=request) + raise errors.InvalidRedirectURIError( + state=request.state, request=request) if not self.request_validator.validate_redirect_uri( request.client_id, request.redirect_uri, request): - raise errors.MismatchingRedirectURIError(state=request.state, request=request) + raise errors.MismatchingRedirectURIError( + state=request.state, request=request) else: request.redirect_uri = self.request_validator.get_default_redirect_uri( - request.client_id, request) + 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(state=request.state, request=request) + raise errors.MissingRedirectURIError( + state=request.state, request=request) # Then check for normal errors. @@ -303,33 +311,34 @@ class AuthorizationCodeGrant(GrantTypeBase): # populated through the use of specific exceptions. if request.response_type is None: raise errors.InvalidRequestError(state=request.state, - description='Missing response_type parameter.', request=request) + description='Missing response_type parameter.', request=request) for param in ('client_id', 'response_type', 'redirect_uri', 'scope', 'state'): if param in request.duplicate_params: raise errors.InvalidRequestError(state=request.state, - description='Duplicate %s parameter.' % param, request=request) + description='Duplicate %s parameter.' % param, request=request) if not self.request_validator.validate_response_type(request.client_id, - request.response_type, request.client, request): + request.response_type, request.client, request): log.debug('Client %s is not authorized to use response_type %s.', request.client_id, request.response_type) raise errors.UnauthorizedClientError(request=request) # REQUIRED. Value MUST be set to "code". if request.response_type != 'code': - raise errors.UnsupportedResponseTypeError(state=request.state, request=request) + raise errors.UnsupportedResponseTypeError( + state=request.state, request=request) # OPTIONAL. The scope of the access request as described by Section 3.3 # http://tools.ietf.org/html/rfc6749#section-3.3 self.validate_scopes(request) return request.scopes, { - 'client_id': request.client_id, - 'redirect_uri': request.redirect_uri, - 'response_type': request.response_type, - 'state': request.state, - 'request': request, + 'client_id': request.client_id, + 'redirect_uri': request.redirect_uri, + 'response_type': request.response_type, + 'state': request.state, + 'request': request, } def validate_token_request(self, request): diff --git a/oauthlib/oauth2/rfc6749/grant_types/base.py b/oauthlib/oauth2/rfc6749/grant_types/base.py index 9121580..33b1be7 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/base.py +++ b/oauthlib/oauth2/rfc6749/grant_types/base.py @@ -24,7 +24,7 @@ class GrantTypeBase(object): def validate_grant_type(self, request): if not self.request_validator.validate_grant_type(request.client_id, - request.grant_type, request.client, request): + request.grant_type, request.client, request): log.debug('Unauthorized from %r (%r) access to grant type %s.', request.client_id, request.client, request.grant_type) raise errors.UnauthorizedClientError(request=request) @@ -32,9 +32,10 @@ class GrantTypeBase(object): def validate_scopes(self, request): if not request.scopes: request.scopes = utils.scope_to_list(request.scope) or utils.scope_to_list( - self.request_validator.get_default_scopes(request.client_id, request)) + self.request_validator.get_default_scopes(request.client_id, request)) log.debug('Validating access to scopes %r for client %r (%r).', request.scopes, request.client_id, request.client) if not self.request_validator.validate_scopes(request.client_id, - request.scopes, request.client, request): - raise errors.InvalidScopeError(state=request.state, request=request) + request.scopes, request.client, request): + raise errors.InvalidScopeError( + state=request.state, request=request) diff --git a/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py b/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py index 9437b11..19f1502 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py +++ b/oauthlib/oauth2/rfc6749/grant_types/client_credentials.py @@ -16,6 +16,7 @@ log = logging.getLogger(__name__) class ClientCredentialsGrant(GrantTypeBase): + """`Client Credentials Grant`_ The client can request an access token using only its client @@ -65,9 +66,9 @@ class ClientCredentialsGrant(GrantTypeBase): .. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2 """ headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store', + 'Pragma': 'no-cache', } try: log.debug('Validating access token request, %r.', request) @@ -92,8 +93,8 @@ class ClientCredentialsGrant(GrantTypeBase): for param in ('grant_type', 'scope'): if param in request.duplicate_params: raise errors.InvalidRequestError(state=request.state, - description='Duplicate %s parameter.' % param, - request=request) + description='Duplicate %s parameter.' % param, + request=request) log.debug('Authenticating client, %r.', request) if not self.request_validator.authenticate_client(request): diff --git a/oauthlib/oauth2/rfc6749/grant_types/implicit.py b/oauthlib/oauth2/rfc6749/grant_types/implicit.py index c3335af..248f84d 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/implicit.py +++ b/oauthlib/oauth2/rfc6749/grant_types/implicit.py @@ -18,6 +18,7 @@ log = logging.getLogger(__name__) class ImplicitGrant(GrantTypeBase): + """`Implicit Grant`_ The implicit grant type is used to obtain access tokens (it does not @@ -225,11 +226,11 @@ class ImplicitGrant(GrantTypeBase): except errors.OAuth2Error as e: log.debug('Client error during validation of %r. %r.', request, e) return {'Location': common.add_params_to_uri(request.redirect_uri, e.twotuples, - fragment=True)}, None, 302 + fragment=True)}, None, 302 token = token_handler.create_token(request, refresh_token=False) return {'Location': common.add_params_to_uri(request.redirect_uri, token.items(), - fragment=True)}, None, 302 + fragment=True)}, None, 302 def validate_authorization_request(self, request): return self.validate_token_request(request) @@ -262,10 +263,12 @@ class ImplicitGrant(GrantTypeBase): # REQUIRED. The client identifier as described in Section 2.2. # http://tools.ietf.org/html/rfc6749#section-2.2 if not request.client_id: - raise errors.MissingClientIdError(state=request.state, request=request) + raise errors.MissingClientIdError( + state=request.state, request=request) if not self.request_validator.validate_client_id(request.client_id, request): - raise errors.InvalidClientIdError(state=request.state, request=request) + raise errors.InvalidClientIdError( + state=request.state, request=request) # OPTIONAL. As described in Section 3.1.2. # http://tools.ietf.org/html/rfc6749#section-3.1.2 @@ -273,7 +276,8 @@ class ImplicitGrant(GrantTypeBase): 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(state=request.state, request=request) + raise errors.InvalidRedirectURIError( + state=request.state, request=request) # The authorization server MUST verify that the redirection URI # to which it will redirect the access token matches a @@ -282,16 +286,19 @@ class ImplicitGrant(GrantTypeBase): # http://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(state=request.state, request=request) + raise errors.MismatchingRedirectURIError( + state=request.state, request=request) else: request.redirect_uri = self.request_validator.get_default_redirect_uri( - request.client_id, request) + 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(state=request.state, request=request) + raise errors.MissingRedirectURIError( + state=request.state, request=request) if not is_absolute_uri(request.redirect_uri): - raise errors.InvalidRedirectURIError(state=request.state, request=request) + raise errors.InvalidRedirectURIError( + state=request.state, request=request) # Then check for normal errors. @@ -306,22 +313,23 @@ class ImplicitGrant(GrantTypeBase): # populated through the use of specific exceptions. if request.response_type is None: raise errors.InvalidRequestError(state=request.state, - description='Missing response_type parameter.', - request=request) + description='Missing response_type parameter.', + request=request) for param in ('client_id', 'response_type', 'redirect_uri', 'scope', 'state'): if param in request.duplicate_params: raise errors.InvalidRequestError(state=request.state, - description='Duplicate %s parameter.' % param, request=request) + description='Duplicate %s parameter.' % param, request=request) # REQUIRED. Value MUST be set to "token". if request.response_type != 'token': - raise errors.UnsupportedResponseTypeError(state=request.state, request=request) + raise errors.UnsupportedResponseTypeError( + state=request.state, request=request) log.debug('Validating use of response_type token for client %r (%r).', request.client_id, request.client) if not self.request_validator.validate_response_type(request.client_id, - request.response_type, request.client, request): + request.response_type, request.client, request): log.debug('Client %s is not authorized to use response_type %s.', request.client_id, request.response_type) raise errors.UnauthorizedClientError(request=request) @@ -331,9 +339,9 @@ class ImplicitGrant(GrantTypeBase): self.validate_scopes(request) return request.scopes, { - 'client_id': request.client_id, - 'redirect_uri': request.redirect_uri, - 'response_type': request.response_type, - 'state': request.state, - 'request': request, + 'client_id': request.client_id, + 'redirect_uri': request.redirect_uri, + 'response_type': request.response_type, + 'state': request.state, + 'request': request, } diff --git a/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py b/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py index f6c27ea..2ca8d92 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py +++ b/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py @@ -16,6 +16,7 @@ log = logging.getLogger(__name__) class RefreshTokenGrant(GrantTypeBase): + """`Refresh token grant`_ .. _`Refresh token grant`: http://tools.ietf.org/html/rfc6749#section-6 @@ -48,9 +49,9 @@ class RefreshTokenGrant(GrantTypeBase): .. _`Section 5.2`: http://tools.ietf.org/html/rfc6749#section-5.2 """ headers = { - 'Content-Type': 'application/json', - 'Cache-Control': 'no-store', - 'Pragma': 'no-cache', + 'Content-Type': 'application/json', + 'Cache-Control': 'no-store', + 'Pragma': 'no-cache', } try: log.debug('Validating refresh token request, %r.', request) @@ -59,7 +60,7 @@ class RefreshTokenGrant(GrantTypeBase): return headers, e.json, e.status_code token = token_handler.create_token(request, - refresh_token=self.issue_new_refresh_tokens) + refresh_token=self.issue_new_refresh_tokens) log.debug('Issuing new token to client id %r (%r), %r.', request.client_id, request.client, token) return headers, json.dumps(token), 200 @@ -103,8 +104,8 @@ class RefreshTokenGrant(GrantTypeBase): raise errors.InvalidGrantError(request=request) original_scopes = utils.scope_to_list( - self.request_validator.get_original_scopes( - request.refresh_token, request)) + self.request_validator.get_original_scopes( + request.refresh_token, request)) if request.scope: request.scopes = utils.scope_to_list(request.scope) @@ -112,8 +113,8 @@ class RefreshTokenGrant(GrantTypeBase): and not self.request_validator.is_within_original_scope( request.scopes, request.refresh_token, request)): log.debug('Refresh token %s lack requested scopes, %r.', - request.refresh_token, request.scopes) + request.refresh_token, request.scopes) raise errors.InvalidScopeError( - state=request.state, request=request) + state=request.state, request=request) else: request.scopes = original_scopes 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 07aa9c1..f1e3dd5 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py +++ b/oauthlib/oauth2/rfc6749/grant_types/resource_owner_password_credentials.py @@ -16,6 +16,7 @@ log = logging.getLogger(__name__) class ResourceOwnerPasswordCredentialsGrant(GrantTypeBase): + """`Resource Owner Password Credentials Grant`_ The resource owner password credentials grant type is suitable in @@ -156,12 +157,12 @@ class ResourceOwnerPasswordCredentialsGrant(GrantTypeBase): for param in ('grant_type', 'username', 'password'): if not getattr(request, param): raise errors.InvalidRequestError( - 'Request is missing %s parameter.' % param, request=request) + 'Request is missing %s parameter.' % param, request=request) for param in ('grant_type', 'username', 'password', 'scope'): if param in request.duplicate_params: raise errors.InvalidRequestError(state=request.state, - description='Duplicate %s parameter.' % param, request=request) + description='Duplicate %s parameter.' % param, request=request) # This error should rarely (if ever) occur if requests are routed to # grant type handlers based on the grant_type parameter. @@ -170,14 +171,15 @@ class ResourceOwnerPasswordCredentialsGrant(GrantTypeBase): log.debug('Validating username %s.', request.username) if not self.request_validator.validate_user(request.username, - request.password, request.client, request): - raise errors.InvalidGrantError('Invalid credentials given.', request=request) + request.password, request.client, request): + raise errors.InvalidGrantError( + 'Invalid credentials given.', request=request) else: if not hasattr(request.client, 'client_id'): raise NotImplementedError( - 'Validate user must set the ' - 'request.client.client_id attribute ' - 'in authenticate_client.') + 'Validate user must set the ' + 'request.client.client_id attribute ' + 'in authenticate_client.') log.debug('Authorizing access to user %r.', request.user) # Ensure client is authorized use of this grant type diff --git a/oauthlib/oauth2/rfc6749/parameters.py b/oauthlib/oauth2/rfc6749/parameters.py index 0e33768..62b63f4 100644 --- a/oauthlib/oauth2/rfc6749/parameters.py +++ b/oauthlib/oauth2/rfc6749/parameters.py @@ -24,7 +24,7 @@ from .utils import list_to_scope, scope_to_list, is_secure_transport def prepare_grant_uri(uri, client_id, response_type, redirect_uri=None, - scope=None, state=None, **kwargs): + scope=None, state=None, **kwargs): """Prepare the authorization grant request URI. The client constructs the request URI by adding the following diff --git a/oauthlib/oauth2/rfc6749/request_validator.py b/oauthlib/oauth2/rfc6749/request_validator.py index 01e025d..e622ff1 100644 --- a/oauthlib/oauth2/rfc6749/request_validator.py +++ b/oauthlib/oauth2/rfc6749/request_validator.py @@ -89,7 +89,7 @@ class RequestValidator(object): raise NotImplementedError('Subclasses must implement this method.') def confirm_redirect_uri(self, client_id, code, redirect_uri, client, - *args, **kwargs): + *args, **kwargs): """Ensure client is authorized to redirect to the redirect_uri requested. If the client specifies a redirect_uri when obtaining code then diff --git a/oauthlib/oauth2/rfc6749/utils.py b/oauthlib/oauth2/rfc6749/utils.py index bc609b5..bfb531a 100644 --- a/oauthlib/oauth2/rfc6749/utils.py +++ b/oauthlib/oauth2/rfc6749/utils.py @@ -80,7 +80,8 @@ def escape(u): def generate_age(issue_time): """Generate a age parameter for MAC authentication draft 00.""" td = datetime.datetime.now() - issue_time - age = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 + age = (td.microseconds + (td.seconds + td.days * 24 * 3600) + * 10 ** 6) / 10 ** 6 return unicode_type(age) diff --git a/oauthlib/uri_validate.py b/oauthlib/uri_validate.py index 7a6a295..e553f32 100644 --- a/oauthlib/uri_validate.py +++ b/oauthlib/uri_validate.py @@ -11,7 +11,7 @@ Thanks Mark Nottingham for this code - https://gist.github.com/138549 from __future__ import unicode_literals import re -### basics +# basics DIGIT = r"[\x30-\x39]" @@ -25,7 +25,7 @@ pct_encoded = r" %% %(HEXDIG)s %(HEXDIG)s" % locals() # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" unreserved = r"(?: %(ALPHA)s | %(DIGIT)s | \- | \. | _ | ~ )" % locals() -# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" +# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" gen_delims = r"(?: : | / | \? | \# | \[ | \] | @ )" # sub-delims = "!" / "$" / "&" / "'" / "(" / ")" @@ -34,19 +34,20 @@ sub_delims = r"""(?: ! | \$ | & | ' | \( | \) | \* | \+ | , | ; | = )""" # pchar = unreserved / pct-encoded / sub-delims / ":" / "@" -pchar = r"(?: %(unreserved)s | %(pct_encoded)s | %(sub_delims)s | : | @ )" % locals() +pchar = r"(?: %(unreserved)s | %(pct_encoded)s | %(sub_delims)s | : | @ )" % locals( +) # reserved = gen-delims / sub-delims reserved = r"(?: %(gen_delims)s | %(sub_delims)s )" % locals() -### scheme +# scheme # scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) scheme = r"%(ALPHA)s (?: %(ALPHA)s | %(DIGIT)s | \+ | \- | \. )*" % locals() -### authority +# authority # dec-octet = DIGIT ; 0-9 # / %x31-39 DIGIT ; 10-99 @@ -62,7 +63,8 @@ dec_octet = r"""(?: %(DIGIT)s | """ % locals() # IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet -IPv4address = r"%(dec_octet)s \. %(dec_octet)s \. %(dec_octet)s \. %(dec_octet)s" % locals() +IPv4address = r"%(dec_octet)s \. %(dec_octet)s \. %(dec_octet)s \. %(dec_octet)s" % locals( +) # h16 = 1*4HEXDIG h16 = r"(?: %(HEXDIG)s ){1,4}" % locals() @@ -101,7 +103,8 @@ IP_literal = r"\[ (?: %(IPv6address)s | %(IPvFuture)s ) \]" % locals() reg_name = r"(?: %(unreserved)s | %(pct_encoded)s | %(sub_delims)s )*" % locals() # userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) -userinfo = r"(?: %(unreserved)s | %(pct_encoded)s | %(sub_delims)s | : )" % locals() +userinfo = r"(?: %(unreserved)s | %(pct_encoded)s | %(sub_delims)s | : )" % locals( +) # host = IP-literal / IPv4address / reg-name host = r"(?: %(IP_literal)s | %(IPv4address)s | %(reg_name)s )" % locals() @@ -160,7 +163,7 @@ query = r"(?: %(pchar)s | / | \? )*" % locals() # fragment = *( pchar / "/" / "?" ) fragment = r"(?: %(pchar)s | / | \? )*" % locals() -### URIs +# URIs # hier-part = "//" authority path-abempty # / path-absolute @@ -184,17 +187,20 @@ relative_part = r"""(?: (?: // %(authority)s %(path_abempty)s ) | ) """ % locals() -# relative-ref = relative-part [ "?" query ] [ "#" fragment ] -relative_ref = r"%(relative_part)s (?: \? %(query)s)? (?: \# %(fragment)s)?" % locals() +# relative-ref = relative-part [ "?" query ] [ "#" fragment ] +relative_ref = r"%(relative_part)s (?: \? %(query)s)? (?: \# %(fragment)s)?" % locals( +) -# URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] -URI = r"^(?: %(scheme)s : %(hier_part)s (?: \? %(query)s )? (?: \# %(fragment)s )? )$" % locals() +# URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] +URI = r"^(?: %(scheme)s : %(hier_part)s (?: \? %(query)s )? (?: \# %(fragment)s )? )$" % locals( +) # URI-reference = URI / relative-ref URI_reference = r"^(?: %(URI)s | %(relative_ref)s )$" % locals() # absolute-URI = scheme ":" hier-part [ "?" query ] -absolute_URI = r"^(?: %(scheme)s : %(hier_part)s (?: \? %(query)s )? )$" % locals() +absolute_URI = r"^(?: %(scheme)s : %(hier_part)s (?: \? %(query)s )? )$" % locals( +) def is_uri(uri): |