Update oauthlib-3.1.1

This commit is contained in:
JonnyWong16 2021-10-14 22:34:45 -07:00
commit d76838a607
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
64 changed files with 4329 additions and 1421 deletions

View file

@ -0,0 +1,9 @@
"""
oauthlib.oopenid.core
~~~~~~~~~~~~~~~~~~~~~~~
This module is an implementation of various logic needed
for consuming and providing OpenID Connect
"""
from .pre_configured import Server
from .userinfo import UserInfoEndpoint

View file

@ -0,0 +1,97 @@
"""
oauthlib.openid.connect.core.endpoints.pre_configured
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module is an implementation of various endpoints needed
for providing OpenID Connect servers.
"""
from oauthlib.oauth2.rfc6749.endpoints import (
AuthorizationEndpoint, IntrospectEndpoint, ResourceEndpoint,
RevocationEndpoint, TokenEndpoint,
)
from oauthlib.oauth2.rfc6749.grant_types import (
AuthorizationCodeGrant as OAuth2AuthorizationCodeGrant,
ClientCredentialsGrant, ImplicitGrant as OAuth2ImplicitGrant,
RefreshTokenGrant, ResourceOwnerPasswordCredentialsGrant,
)
from oauthlib.oauth2.rfc6749.tokens import BearerToken
from ..grant_types import AuthorizationCodeGrant, HybridGrant, ImplicitGrant
from ..grant_types.dispatchers import (
AuthorizationCodeGrantDispatcher, AuthorizationTokenGrantDispatcher,
ImplicitTokenGrantDispatcher,
)
from ..tokens import JWTToken
from .userinfo import UserInfoEndpoint
class Server(AuthorizationEndpoint, IntrospectEndpoint, TokenEndpoint,
ResourceEndpoint, RevocationEndpoint, UserInfoEndpoint):
"""An all-in-one endpoint featuring all four major grant types."""
def __init__(self, request_validator, token_expires_in=None,
token_generator=None, refresh_token_generator=None,
*args, **kwargs):
"""Construct a new all-grants-in-one server.
:param request_validator: An implementation of
oauthlib.oauth2.RequestValidator.
:param token_expires_in: An int or a function to generate a token
expiration offset (in seconds) given a
oauthlib.common.Request object.
:param token_generator: A function to generate a token from a request.
:param refresh_token_generator: A function to generate a token from a
request for the refresh token.
:param kwargs: Extra parameters to pass to authorization-,
token-, resource-, and revocation-endpoint constructors.
"""
self.auth_grant = OAuth2AuthorizationCodeGrant(request_validator)
self.implicit_grant = OAuth2ImplicitGrant(request_validator)
self.password_grant = ResourceOwnerPasswordCredentialsGrant(
request_validator)
self.credentials_grant = ClientCredentialsGrant(request_validator)
self.refresh_grant = RefreshTokenGrant(request_validator)
self.openid_connect_auth = AuthorizationCodeGrant(request_validator)
self.openid_connect_implicit = ImplicitGrant(request_validator)
self.openid_connect_hybrid = HybridGrant(request_validator)
self.bearer = BearerToken(request_validator, token_generator,
token_expires_in, refresh_token_generator)
self.jwt = JWTToken(request_validator, token_generator,
token_expires_in, refresh_token_generator)
self.auth_grant_choice = AuthorizationCodeGrantDispatcher(default_grant=self.auth_grant, oidc_grant=self.openid_connect_auth)
self.implicit_grant_choice = ImplicitTokenGrantDispatcher(default_grant=self.implicit_grant, oidc_grant=self.openid_connect_implicit)
# See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#Combinations for valid combinations
# internally our AuthorizationEndpoint will ensure they can appear in any order for any valid combination
AuthorizationEndpoint.__init__(self, default_response_type='code',
response_types={
'code': self.auth_grant_choice,
'token': self.implicit_grant_choice,
'id_token': self.openid_connect_implicit,
'id_token token': self.openid_connect_implicit,
'code token': self.openid_connect_hybrid,
'code id_token': self.openid_connect_hybrid,
'code id_token token': self.openid_connect_hybrid,
'none': self.auth_grant
},
default_token_type=self.bearer)
self.token_grant_choice = AuthorizationTokenGrantDispatcher(request_validator, default_grant=self.auth_grant, oidc_grant=self.openid_connect_auth)
TokenEndpoint.__init__(self, default_grant_type='authorization_code',
grant_types={
'authorization_code': self.token_grant_choice,
'password': self.password_grant,
'client_credentials': self.credentials_grant,
'refresh_token': self.refresh_grant,
},
default_token_type=self.bearer)
ResourceEndpoint.__init__(self, default_token='Bearer',
token_types={'Bearer': self.bearer, 'JWT': self.jwt})
RevocationEndpoint.__init__(self, request_validator)
IntrospectEndpoint.__init__(self, request_validator)
UserInfoEndpoint.__init__(self, request_validator)

View file

@ -0,0 +1,99 @@
"""
oauthlib.openid.connect.core.endpoints.userinfo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module is an implementation of userinfo endpoint.
"""
import json
import logging
from oauthlib.common import Request
from oauthlib.oauth2.rfc6749 import errors
from oauthlib.oauth2.rfc6749.endpoints.base import (
BaseEndpoint, catch_errors_and_unavailability,
)
from oauthlib.oauth2.rfc6749.tokens import BearerToken
log = logging.getLogger(__name__)
class UserInfoEndpoint(BaseEndpoint):
"""Authorizes access to userinfo resource.
"""
def __init__(self, request_validator):
self.bearer = BearerToken(request_validator, None, None, None)
self.request_validator = request_validator
BaseEndpoint.__init__(self)
@catch_errors_and_unavailability
def create_userinfo_response(self, uri, http_method='GET', body=None, headers=None):
"""Validate BearerToken and return userinfo from RequestValidator
The UserInfo Endpoint MUST return a
content-type header to indicate which format is being returned. The
content-type of the HTTP response MUST be application/json if the
response body is a text JSON object; the response body SHOULD be encoded
using UTF-8.
"""
request = Request(uri, http_method, body, headers)
request.scopes = ["openid"]
self.validate_userinfo_request(request)
claims = self.request_validator.get_userinfo_claims(request)
if claims is None:
log.error('Userinfo MUST have claims for %r.', request)
raise errors.ServerError(status_code=500)
if isinstance(claims, dict):
resp_headers = {
'Content-Type': 'application/json'
}
if "sub" not in claims:
log.error('Userinfo MUST have "sub" for %r.', request)
raise errors.ServerError(status_code=500)
body = json.dumps(claims)
elif isinstance(claims, str):
resp_headers = {
'Content-Type': 'application/jwt'
}
body = claims
else:
log.error('Userinfo return unknown response for %r.', request)
raise errors.ServerError(status_code=500)
log.debug('Userinfo access valid for %r.', request)
return resp_headers, body, 200
def validate_userinfo_request(self, request):
"""Ensure the request is valid.
5.3.1. UserInfo Request
The Client sends the UserInfo Request using either HTTP GET or HTTP
POST. The Access Token obtained from an OpenID Connect Authentication
Request MUST be sent as a Bearer Token, per Section 2 of OAuth 2.0
Bearer Token Usage [RFC6750].
It is RECOMMENDED that the request use the HTTP GET method and the
Access Token be sent using the Authorization header field.
The following is a non-normative example of a UserInfo Request:
GET /userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG
5.3.3. UserInfo Error Response
When an error condition occurs, the UserInfo Endpoint returns an Error
Response as defined in Section 3 of OAuth 2.0 Bearer Token Usage
[RFC6750]. (HTTP errors unrelated to RFC 6750 are returned to the User
Agent using the appropriate HTTP status code.)
The following is a non-normative example of a UserInfo Error Response:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token",
error_description="The Access Token expired"
"""
if not self.bearer.validate_request(request):
raise errors.InvalidTokenError()
if "openid" not in request.scopes:
raise errors.InsufficientScopeError()