import calendar import functools import json from django.core.exceptions import ObjectDoesNotExist from django.http import HttpResponse, HttpResponseForbidden from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods from oauth2_provider.models import get_access_token_model from oauth2_provider.oauth2_backends import OAuthLibCore from oauth2_provider.views import ClientProtectedScopedResourceView from oauthlib.oauth2 import Server # from apps.gooyal_oauth2.validators import IntrospectOAuth2Validator # @method_decorator(csrf_exempt, name="dispatch") # class IntrospectTokenView(ClientProtectedScopedResourceView): # """ # Implements an endpoint for token introspection based # on RFC 7662 https://tools.ietf.org/html/rfc7662 # # To access this view the request must pass a OAuth2 Bearer Token # which is allowed to access the scope `introspection`. # """ # required_scopes = ["introspection"] # # @staticmethod # def get_token_response(token_value=None): # try: # token = get_access_token_model().objects.get(token=token_value) # except ObjectDoesNotExist: # return HttpResponse( # content=json.dumps({"active": False}), # status=401, # content_type="application/json" # ) # else: # if token.is_valid(): # data = { # "active": True, # "scope": token.scope, # "exp": int(calendar.timegm(token.expires.timetuple())), # } # if token.application: # data["client_id"] = token.application.client_id # if token.user: # data["username"] = token.user.get_username() # return HttpResponse(content=json.dumps(data), status=200, content_type="application/json") # else: # return HttpResponse(content=json.dumps({ # "active": False, # }), status=200, content_type="application/json") # # def get(self, request, *args, **kwargs): # """ # Get the token from the URL parameters. # URL: https://example.com/introspect?token=mF_9.B5f-4.1JqM # # :param request: # :param args: # :param kwargs: # :return: # """ # return self.get_token_response(request.GET.get("token", None)) # # def post(self, request, *args, **kwargs): # """ # Get the token from the body form parameters. # Body: token=mF_9.B5f-4.1JqM # # :param request: # :param args: # :param kwargs: # :return: # """ # return self.get_token_response(request.POST.get("token", None)) # def protected_resource(scopes=None): # """ # Implementation of protected_resource decorator that saves the client on the # request for the view function to use. # # Cribbed from django-oauth-toolkit. # """ # _scopes = scopes or [] # # def decorator(view_func): # @functools.wraps(view_func) # def _validate(request, *args, **kwargs): # validator = IntrospectOAuth2Validator() # core = OAuthLibCore(Server(validator)) # valid, oauthlib_req = core.verify_request(request, scopes=_scopes) # if valid: # request.client = oauthlib_req.client # request.resource_owner = oauthlib_req.user # return view_func(request, *args, **kwargs) # return HttpResponseForbidden() # # return _validate # # return decorator # # # @require_http_methods(['GET', 'POST']) # @csrf_exempt # @protected_resource(scopes=['introspection']) # def introspect_token(request): # """ # Version of the introspection view protected by a regular scope instead of # read-write scopes. # # Also allows for the required scope to be changed using a setting. # """ # if request.method == 'GET': # token = request.GET.get("token", None) # else: # token = request.POST.get("token", None) # return IntrospectTokenView.get_token_response(token) # @require_POST # @csrf_exempt # @protected_resource(scopes=[settings.REGISTER_SCOPE_SCOPE]) # def register_scope(request): # """ # Implements an endpoint for registering a scope. # """ # #  Get the scope data from the request body # scope_data = json.loads(request.body) if request.body else {} # try: # try: # #  If a scope with the given name already exists, find it # scope = Scope.objects.get(name=scope_data['name']) # except Scope.DoesNotExist: # #  If no scope with the given name exists, create it # _ = Scope.objects.create( # application=request.client, # name=scope_data['name'], # description=scope_data['description'], # is_default=scope_data.get('is_default', False) # ) # #  Respond with a 201 Created # return HttpResponse(status=201) # except KeyError as exc: # #  A key missing in the data should be reported as a bad request # return HttpResponse( # status=400, # content="'{}' must be given in request data".format(exc.args[0]), # content_type='text/plain' # ) # #  If the scope does exist, check that the current application is the # #  owner of the scope before updating it # if scope.application and scope.application == request.client: # scope.description = scope_data['description'] # scope.is_default = scope_data.get('is_default', False) # scope.save() # return HttpResponse(status=200) # else: # return HttpResponse(status=403)