Source code for simple_openid_connect.integrations.django.decorators
"""View-function decorators"""importloggingfromfunctoolsimportwrapsfromhttpimportHTTPStatusfromtypingimportAny,Callable,Optional,TypeVar,Unionfromdjango.confimportsettingsfromdjango.httpimportHttpRequest,HttpResponse,JsonResponsefromsimple_openid_connect.dataimportJwtAccessToken,TokenIntrospectionErrorResponsefromsimple_openid_connect.exceptionsimportValidationErrorfromsimple_openid_connect.integrations.djangoimportmodelsfromsimple_openid_connect.integrations.django.appsimportOpenidAppConfigfromsimple_openid_connect.utilsimportis_application_jsonlogger=logging.getLogger(__name__)View_Return=TypeVar("View_Return",bound=HttpResponse)def_invalid_token_response(request:HttpRequest)->HttpResponse:if"Accept"inrequest.headers.keys()andis_application_json(request.headers["Accept"]):returnJsonResponse(status=HTTPStatus.UNAUTHORIZED,headers={"WWW-Authenticate":"Bearer"},data={"error":"invalid_token","error_description":"the used access token is not valid or does not grant enough access",},)else:returnHttpResponse(status=HTTPStatus.UNAUTHORIZED,content="the used access token is not valid or does not grant enough access",headers={"WWW-Authenticate":"Bearer"},)
[docs]defaccess_token_required(*,required_scopes:Optional[str]=None)->Callable[...,Union[HttpResponse,View_Return]]:""" Decorator for views that checks that the request is authenticated using a valid access token, early-returning an appropriate http error response if necessary. :param required_scopes: Scopes to which the access token needs to have access. If not given, use the `settings.OPENID_SCOPE` value which defaults to "openid". :raises UnsupportedByProviderError: If the provider does not support token introspection. """ifrequired_scopesisNone:_required_scopes=OpenidAppConfig.get_instance().safe_settings.OPENID_SCOPEelse:_required_scopes=required_scopesdefactual_decorator(view_func:Callable[...,View_Return],)->Callable[...,View_Return]:@wraps(view_func)defwrapped_view(request:HttpRequest,*args:Any,**kwargs:Any)->Union[HttpResponse,View_Return]:# verify that an Authorization Header of type Bearer is presentif"Authorization"notinrequest.headers.keys()ornotrequest.headers["Authorization"].startswith("Bearer "):returnHttpResponse(status=HTTPStatus.UNAUTHORIZED,headers={"WWW-Authenticate":"Bearer"},)oidc_client=OpenidAppConfig.get_instance().get_client(request)raw_token=request.headers["Authorization"].split(" ",1)[1]try:(request.user,_,)=OpenidAppConfig.get_instance().user_mapper.handle_federated_access_token(raw_token,oidc_client,_required_scopes)exceptValidationError:return_invalid_token_response(request)# execute the decorated view functionreturnview_func(request,*args,**kwargs)returnwrapped_view# type: ignorereturnactual_decorator# type: ignore