# # steering, Programme/schedule management for AURA # # Copyright (C) 2011-2017, 2020, Ernesto Rico Schmidt # Copyright (C) 2017-2019, Ingo Leindecker # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more # details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from drf_spectacular.extensions import OpenApiAuthenticationExtension from drf_spectacular.plumbing import build_bearer_security_scheme_object from oidc_provider.lib.utils.oauth2 import extract_access_token from oidc_provider.models import Token from rest_framework import authentication, exceptions class OidcOauth2Auth(authentication.BaseAuthentication): def authenticate(self, request): access_token = extract_access_token(request) if not access_token: # not this kind of auth return None oauth2_token = None try: oauth2_token = Token.objects.get(access_token=access_token) except Token.DoesNotExist: raise exceptions.AuthenticationFailed("The oauth2 token is invalid") if oauth2_token.has_expired(): raise exceptions.AuthenticationFailed("The oauth2 token has expired") return oauth2_token.user, None class OidcOauth2AuthenticationScheme(OpenApiAuthenticationExtension): target_class = "program.auth.OidcOauth2Auth" name = "tokenAuth" def get_security_definition(self, auto_schema): # One might be inclined to return a list here, because the bearer token # can also be passed as an `access_token` query parameter. # Officially this seems to be supported, but once we return a list # the authorization helper in the generated documentation is empty, # so we only return the primary mode instead. return build_bearer_security_scheme_object("Authorization", "Bearer") # This should work, but doesn’t for the reasons above: # # return [ # build_bearer_security_scheme_object("Authorization", "Bearer"), # { # "type": "apiKey", # "in": "query", # "name": "access_token", # } # ]