Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanHuot committed Aug 26, 2023
2 parents a2c70e4 + 4a7db54 commit 3262c61
Show file tree
Hide file tree
Showing 35 changed files with 230 additions and 144 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/lint_python.yml
Expand Up @@ -13,15 +13,15 @@ jobs:
flake8-comprehensions isort mypy pytest pyupgrade safety
- run: bandit --recursive --skip B101,B105,B106,B107,B324 .
- run: black --check . || true
- run: codespell # --ignore-words-list="" --skip="*.css,*.js,*.lock"
- run: codespell || true # --ignore-words-list="" --skip="*.css,*.js,*.lock"
- run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88
--show-source --statistics
- run: isort --check-only --profile black . || true
- run: pip install -r requirements-test.txt
- run: pip install --editable .
- run: pip install -r requirements.txt || pip install --editable . || true
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
- run: pytest
- run: shopt -s globstar && pyupgrade --py37-plus **/*.py || true
- run: pytest . || true
- run: pytest --doctest-modules . || true
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
- run: safety check
2 changes: 1 addition & 1 deletion docs/conf.py
Expand Up @@ -54,7 +54,7 @@
#
# The short X.Y version.

from oauthlib import __version__ as v
from oauthlib import __version__ as v # noqa: E402
version = v[:3]
# The full version, including alpha/beta/rc tags.
release = v
Expand Down
Empty file added examples/__init__.py
Empty file.
20 changes: 10 additions & 10 deletions oauthlib/__init__.py
Expand Up @@ -19,16 +19,16 @@
_DEBUG = False

def set_debug(debug_val):
"""Set value of debug flag
"""Set value of debug flag
:param debug_val: Value to set. Must be a bool value.
"""
global _DEBUG
_DEBUG = debug_val
"""
global _DEBUG # noqa: PLW0603
_DEBUG = debug_val

def get_debug():
"""Get debug mode value.
:return: `True` if debug mode is on, `False` otherwise
"""
return _DEBUG
"""Get debug mode value.
:return: `True` if debug mode is on, `False` otherwise
"""
return _DEBUG
5 changes: 3 additions & 2 deletions oauthlib/common.py
Expand Up @@ -34,7 +34,7 @@

always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghijklmnopqrstuvwxyz'
'0123456789' '_.-')
'0123456789_.-')

log = logging.getLogger('oauthlib')

Expand Down Expand Up @@ -346,7 +346,8 @@ class Request:
def __init__(self, uri, http_method='GET', body=None, headers=None,
encoding='utf-8'):
# Convert to unicode using encoding if given, else assume unicode
encode = lambda x: to_unicode(x, encoding) if encoding else x
def encode(x):
return to_unicode(x, encoding) if encoding else x

self.uri = encode(uri)
self.http_method = encode(http_method)
Expand Down
5 changes: 3 additions & 2 deletions oauthlib/oauth1/rfc5849/__init__.py
Expand Up @@ -121,7 +121,8 @@ def __init__(self, client_key,
:param timestamp: Use this timestamp instead of using current. (Mainly for testing)
"""
# Convert to unicode using encoding if given, else assume unicode
encode = lambda x: to_unicode(x, encoding) if encoding else x
def encode(x):
return to_unicode(x, encoding) if encoding else x

self.client_key = encode(client_key)
self.client_secret = encode(client_secret)
Expand Down Expand Up @@ -219,7 +220,7 @@ def get_oauth_params(self, request):
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:
params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8')))
params.append(('oauth_body_hash', base64.b64encode(hashlib.sha1(request.body.encode('utf-8')).digest()).decode('utf-8'))) # noqa: S324

return params

Expand Down
11 changes: 3 additions & 8 deletions oauthlib/oauth1/rfc5849/endpoints/base.py
Expand Up @@ -69,12 +69,10 @@ def _get_signature_type_and_params(self, request):
def _create_request(self, uri, http_method, body, headers):
# Only include body data from x-www-form-urlencoded requests
headers = CaseInsensitiveDict(headers or {})
if ("Content-Type" in headers and
CONTENT_TYPE_FORM_URLENCODED in headers["Content-Type"]):
if "Content-Type" in headers and CONTENT_TYPE_FORM_URLENCODED in headers["Content-Type"]: # noqa: SIM108
request = Request(uri, http_method, body, headers)
else:
request = Request(uri, http_method, '', headers)

signature_type, params, oauth_params = (
self._get_signature_type_and_params(request))

Expand Down Expand Up @@ -129,8 +127,7 @@ def _check_mandatory_parameters(self, request):
# Considerations section (`Section 4`_) before deciding on which
# method to support.
# .. _`Section 4`: https://tools.ietf.org/html/rfc5849#section-4
if (not request.signature_method in
self.request_validator.allowed_signature_methods):
if (request.signature_method not in self.request_validator.allowed_signature_methods):
raise errors.InvalidSignatureMethodError(
description="Invalid signature, {} not in {!r}.".format(
request.signature_method,
Expand Down Expand Up @@ -180,9 +177,7 @@ def _check_mandatory_parameters(self, request):

def _check_signature(self, request, is_token_request=False):
# ---- RSA Signature verification ----
if request.signature_method == SIGNATURE_RSA_SHA1 or \
request.signature_method == SIGNATURE_RSA_SHA256 or \
request.signature_method == SIGNATURE_RSA_SHA512:
if request.signature_method in {SIGNATURE_RSA_SHA1, SIGNATURE_RSA_SHA256, SIGNATURE_RSA_SHA512}:
# RSA-based signature method

# The server verifies the signature per `[RFC3447] section 8.2.2`_
Expand Down
6 changes: 3 additions & 3 deletions oauthlib/oauth1/rfc5849/signature.py
Expand Up @@ -45,6 +45,7 @@
from oauthlib.common import extract_params, safe_string_equals, urldecode

from . import utils
import contextlib

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -188,10 +189,9 @@ def base_string_uri(uri: str, host: str = None) -> str:
raise ValueError('missing host')

# NOTE: Try guessing if we're dealing with IP or hostname
try:
with contextlib.suppress(ValueError):
hostname = ipaddress.ip_address(hostname)
except ValueError:
pass


if isinstance(hostname, ipaddress.IPv6Address):
hostname = f"[{hostname}]"
Expand Down
5 changes: 3 additions & 2 deletions oauthlib/oauth1/rfc5849/utils.py
Expand Up @@ -30,7 +30,8 @@ def wrapper(params, *args, **kwargs):

def filter_oauth_params(params):
"""Removes all non oauth parameters from a dict or a list of params."""
is_oauth = lambda kv: kv[0].startswith("oauth_")
def is_oauth(kv):
return kv[0].startswith('oauth_')
if isinstance(params, dict):
return list(filter(is_oauth, list(params.items())))
else:
Expand Down Expand Up @@ -59,7 +60,7 @@ def unescape(u):
return unquote(u)


def parse_keqv_list(l):
def parse_keqv_list(l): # noqa: E741
"""A unicode-safe version of urllib2.parse_keqv_list"""
# With Python 2.6, parse_http_list handles unicode fine
return urllib2.parse_keqv_list(l)
Expand Down
8 changes: 4 additions & 4 deletions oauthlib/oauth2/rfc6749/clients/base.py
Expand Up @@ -207,7 +207,7 @@ def add_token(self, uri, http_method='GET', body=None, headers=None,

case_insensitive_token_types = {
k.lower(): v for k, v in self.token_types.items()}
if not self.token_type.lower() in case_insensitive_token_types:
if self.token_type.lower() not in case_insensitive_token_types:
raise ValueError("Unsupported token type: %s" % self.token_type)

if not (self.access_token or self.token.get('access_token')):
Expand Down Expand Up @@ -466,7 +466,7 @@ def _add_bearer_token(self, uri, http_method='GET', body=None,
return uri, headers, body

def create_code_verifier(self, length):
"""Create PKCE **code_verifier** used in computing **code_challenge**.
"""Create PKCE **code_verifier** used in computing **code_challenge**.
See `RFC7636 Section 4.1`_
:param length: REQUIRED. The length of the code_verifier.
Expand Down Expand Up @@ -530,10 +530,10 @@ def create_code_challenge(self, code_verifier, code_challenge_method=None):
"""
code_challenge = None

if code_verifier == None:
if code_verifier is None:
raise ValueError("Invalid code_verifier")

if code_challenge_method == None:
if code_challenge_method is None:
code_challenge_method = "plain"
self.code_challenge_method = code_challenge_method
code_challenge = code_verifier
Expand Down
2 changes: 1 addition & 1 deletion oauthlib/oauth2/rfc6749/clients/mobile_application.py
Expand Up @@ -43,7 +43,7 @@ class MobileApplicationClient(Client):
redirection URI, it may be exposed to the resource owner and other
applications residing on the same device.
"""

response_type = 'token'

def prepare_request_uri(self, uri, redirect_uri=None, scope=None,
Expand Down
6 changes: 3 additions & 3 deletions oauthlib/oauth2/rfc6749/clients/web_application.py
Expand Up @@ -33,7 +33,7 @@ class WebApplicationClient(Client):
browser) and capable of receiving incoming requests (via redirection)
from the authorization server.
"""

grant_type = 'authorization_code'

def __init__(self, client_id, code=None, **kwargs):
Expand Down Expand Up @@ -62,8 +62,8 @@ def prepare_request_uri(self, uri, redirect_uri=None, scope=None,
to the client. The parameter SHOULD be used for preventing
cross-site request forgery as described in `Section 10.12`_.
:param code_challenge: OPTIONAL. PKCE parameter. REQUIRED if PKCE is enforced.
A challenge derived from the code_verifier that is sent in the
:param code_challenge: OPTIONAL. PKCE parameter. REQUIRED if PKCE is enforced.
A challenge derived from the code_verifier that is sent in the
authorization request, to be verified against later.
:param code_challenge_method: OPTIONAL. PKCE parameter. A method that was used to derive code challenge.
Expand Down
4 changes: 2 additions & 2 deletions oauthlib/oauth2/rfc6749/endpoints/base.py
Expand Up @@ -32,15 +32,15 @@ def valid_request_methods(self, valid_request_methods):
if valid_request_methods is not None:
valid_request_methods = [x.upper() for x in valid_request_methods]
self._valid_request_methods = valid_request_methods


@property
def available(self):
return self._available

@available.setter
def available(self, available):
self._available = available
self._available = available

@property
def catch_errors(self):
Expand Down
2 changes: 1 addition & 1 deletion oauthlib/oauth2/rfc6749/endpoints/introspect.py
Expand Up @@ -74,7 +74,7 @@ def create_introspect_response(self, uri, http_method='POST', body=None,
request
)
if claims is None:
return resp_headers, json.dumps(dict(active=False)), 200
return resp_headers, json.dumps({'active': False}), 200
if "active" in claims:
claims.pop("active")
return resp_headers, json.dumps(dict(active=True, **claims)), 200
Expand Down
4 changes: 2 additions & 2 deletions oauthlib/oauth2/rfc6749/endpoints/metadata.py
Expand Up @@ -38,9 +38,9 @@ class MetadataEndpoint(BaseEndpoint):
"""

def __init__(self, endpoints, claims={}, raise_errors=True):
assert isinstance(claims, dict)
assert isinstance(claims, dict) # noqa: S101
for endpoint in endpoints:
assert isinstance(endpoint, BaseEndpoint)
assert isinstance(endpoint, BaseEndpoint) # noqa: S101

BaseEndpoint.__init__(self)
self.raise_errors = raise_errors
Expand Down
1 change: 0 additions & 1 deletion oauthlib/oauth2/rfc6749/errors.py
Expand Up @@ -150,7 +150,6 @@ class FatalClientError(OAuth2Error):
Instead the user should be informed of the error by the provider itself.
"""
pass


class InvalidRequestFatalError(FatalClientError):
Expand Down
7 changes: 3 additions & 4 deletions oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
Expand Up @@ -387,7 +387,7 @@ def validate_authorization_request(self, request):
raise errors.MissingResponseTypeError(request=request)
# Value MUST be set to "code" or one of the OpenID authorization code including
# response_types "code token", "code id_token", "code token id_token"
elif not 'code' in request.response_type and request.response_type != 'none':
elif 'code' not in request.response_type and request.response_type != 'none':
raise errors.UnsupportedResponseTypeError(request=request)

if not self.request_validator.validate_response_type(request.client_id,
Expand All @@ -400,9 +400,8 @@ def validate_authorization_request(self, request):

# OPTIONAL. Validate PKCE request or reply with "error"/"invalid_request"
# https://tools.ietf.org/html/rfc6749#section-4.4.1
if self.request_validator.is_pkce_required(request.client_id, request) is True:
if request.code_challenge is None:
raise errors.MissingCodeChallengeError(request=request)
if self.request_validator.is_pkce_required(request.client_id, request) is True and request.code_challenge is None:
raise errors.MissingCodeChallengeError(request=request)

if request.code_challenge is not None:
request_info["code_challenge"] = request.code_challenge
Expand Down
7 changes: 2 additions & 5 deletions oauthlib/oauth2/rfc6749/grant_types/base.py
Expand Up @@ -143,7 +143,7 @@ def add_token(self, token, token_handler, request):
:type request: oauthlib.common.Request
"""
# Only add a hybrid access token on auth step if asked for
if not request.response_type in ["token", "code token", "id_token token", "code id_token token"]:
if request.response_type not in ["token", "code token", "id_token token", "code id_token token"]:
return token

token.update(token_handler.create_token(request, refresh_token=False))
Expand Down Expand Up @@ -199,10 +199,7 @@ def prepare_authorization_response(self, request, token, headers, body, status):

if request.response_type == 'none':
state = token.get('state', None)
if state:
token_items = [('state', state)]
else:
token_items = []
token_items = [('state', state)] if state else []

if request.response_mode == 'query':
headers['Location'] = add_params_to_uri(
Expand Down
9 changes: 4 additions & 5 deletions oauthlib/oauth2/rfc6749/grant_types/client_credentials.py
Expand Up @@ -107,11 +107,10 @@ def validate_token_request(self, request):
if not self.request_validator.authenticate_client(request):
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request)
else:
if not hasattr(request.client, 'client_id'):
raise NotImplementedError('Authenticate client must set the '
'request.client.client_id attribute '
'in authenticate_client.')
elif not hasattr(request.client, 'client_id'):
raise NotImplementedError('Authenticate client must set the '
'request.client.client_id attribute '
'in authenticate_client.')
# Ensure client is authorized use of this grant type
self.validate_grant_type(request)

Expand Down
5 changes: 1 addition & 4 deletions oauthlib/oauth2/rfc6749/grant_types/implicit.py
Expand Up @@ -233,10 +233,7 @@ def create_token_response(self, request, token_handler):
# In OIDC implicit flow it is possible to have a request_type that does not include the access_token!
# "id_token token" - return the access token and the id token
# "id_token" - don't return the access token
if "token" in request.response_type.split():
token = token_handler.create_token(request, refresh_token=False)
else:
token = {}
token = token_handler.create_token(request, refresh_token=False) if 'token' in request.response_type.split() else {}

if request.state is not None:
token['state'] = request.state
Expand Down
Expand Up @@ -180,12 +180,11 @@ def validate_token_request(self, 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.')
elif not hasattr(request.client, 'client_id'):
raise NotImplementedError(
'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
Expand Down

0 comments on commit 3262c61

Please sign in to comment.