structure saas with tools
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
"""authlib.oauth2.rfc6749.authenticate_client.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Registry of client authentication methods, with 3 built-in methods:
|
||||
|
||||
1. client_secret_basic
|
||||
2. client_secret_post
|
||||
3. none
|
||||
|
||||
The "client_secret_basic" method is used a lot in examples of `RFC6749`_,
|
||||
but the concept of naming are introduced in `RFC7591`_.
|
||||
|
||||
.. _`RFC6749`: https://tools.ietf.org/html/rfc6749
|
||||
.. _`RFC7591`: https://tools.ietf.org/html/rfc7591
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from .errors import InvalidClientError
|
||||
from .util import extract_basic_authorization
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__all__ = ["ClientAuthentication"]
|
||||
|
||||
|
||||
class ClientAuthentication:
|
||||
def __init__(self, query_client):
|
||||
self.query_client = query_client
|
||||
self._methods = {
|
||||
"none": authenticate_none,
|
||||
"client_secret_basic": authenticate_client_secret_basic,
|
||||
"client_secret_post": authenticate_client_secret_post,
|
||||
}
|
||||
|
||||
def register(self, method, func):
|
||||
self._methods[method] = func
|
||||
|
||||
def authenticate(self, request, methods, endpoint):
|
||||
for method in methods:
|
||||
func = self._methods[method]
|
||||
client = func(self.query_client, request)
|
||||
if client and client.check_endpoint_auth_method(method, endpoint):
|
||||
request.auth_method = method
|
||||
return client
|
||||
|
||||
if "client_secret_basic" in methods:
|
||||
raise InvalidClientError(
|
||||
state=request.state,
|
||||
status_code=401,
|
||||
description=f"The client cannot authenticate with methods: {methods}",
|
||||
)
|
||||
raise InvalidClientError(
|
||||
state=request.state,
|
||||
description=f"The client cannot authenticate with methods: {methods}",
|
||||
)
|
||||
|
||||
def __call__(self, request, methods, endpoint="token"):
|
||||
return self.authenticate(request, methods, endpoint)
|
||||
|
||||
|
||||
def authenticate_client_secret_basic(query_client, request):
|
||||
"""Authenticate client by ``client_secret_basic`` method. The client
|
||||
uses HTTP Basic for authentication.
|
||||
"""
|
||||
client_id, client_secret = extract_basic_authorization(request.headers)
|
||||
if client_id and client_secret:
|
||||
client = _validate_client(query_client, client_id, request.state, 401)
|
||||
if client.check_client_secret(client_secret):
|
||||
log.debug(f'Authenticate {client_id} via "client_secret_basic" success')
|
||||
return client
|
||||
log.debug(f'Authenticate {client_id} via "client_secret_basic" failed')
|
||||
|
||||
|
||||
def authenticate_client_secret_post(query_client, request):
|
||||
"""Authenticate client by ``client_secret_post`` method. The client
|
||||
uses POST parameters for authentication.
|
||||
"""
|
||||
data = request.form
|
||||
client_id = data.get("client_id")
|
||||
client_secret = data.get("client_secret")
|
||||
if client_id and client_secret:
|
||||
client = _validate_client(query_client, client_id, request.state)
|
||||
if client.check_client_secret(client_secret):
|
||||
log.debug(f'Authenticate {client_id} via "client_secret_post" success')
|
||||
return client
|
||||
log.debug(f'Authenticate {client_id} via "client_secret_post" failed')
|
||||
|
||||
|
||||
def authenticate_none(query_client, request):
|
||||
"""Authenticate public client by ``none`` method. The client
|
||||
does not have a client secret.
|
||||
"""
|
||||
client_id = request.client_id
|
||||
if client_id and not request.data.get("client_secret"):
|
||||
client = _validate_client(query_client, client_id, request.state)
|
||||
log.debug(f'Authenticate {client_id} via "none" success')
|
||||
return client
|
||||
log.debug(f'Authenticate {client_id} via "none" failed')
|
||||
|
||||
|
||||
def _validate_client(query_client, client_id, state=None, status_code=400):
|
||||
if client_id is None:
|
||||
raise InvalidClientError(
|
||||
state=state,
|
||||
status_code=status_code,
|
||||
description="Missing 'client_id' parameter.",
|
||||
)
|
||||
|
||||
client = query_client(client_id)
|
||||
if not client:
|
||||
raise InvalidClientError(
|
||||
state=state,
|
||||
status_code=status_code,
|
||||
description="The client does not exist on this server.",
|
||||
)
|
||||
|
||||
return client
|
||||
Reference in New Issue
Block a user