So I'm trying to create a PUT endpoint for editing post data. In the endpoint the post id is given in the URL then the new post dated is inserted into the entity. The issue I'm running into is that request isn't coming through on the authenticator (I'm using Cognito to authenticate, not super important for the error). So even though you can see I'm clearly passing in data, the request isn't coming through on the wrapped_view
in the cognito_authenticator
function. Why is this happening? The error I'm getting is:
"wrapped_view() missing 1 required positional argument: 'request'"
Test.py
def test_edit(self):
response = self.client.put(reverse('edit_post_by_id', kwargs={'post_id': str(self.post.uuid)}),
data={'body': 'updated text #update'},
content_type='application/json',
**{'HTTP_AUTHORIZATION': f'bearer {self.cognito.access_token}'})
self.assertEqual(response.status_code, status.HTTP_200_OK)
View.py
@api_view(['PUT'])
@method_decorator(cognito_authenticator)
def edit_post(request, post_id):
try:
post = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
return JsonResponse(dict(error=f'Post id: {post_id} does not exists'), status=status.HTTP_400_BAD_REQUEST)
authenticator
def cognito_authenticator(view_func=None):
if view_func is None:
return partial(cognito_authenticator)
@wraps(view_func)
def wrapped_view(request, *args, **kwargs):
# Check the cognito token from the request.
auth = request.headers.get("Authorization", None)
if not auth:
return Response(dict(error='Authorization header expected'), status=status.HTTP_401_UNAUTHORIZED)
parts = auth.split()
if parts[0].lower() != "bearer":
return Response(dict(error='Authorization header must start with bearer'),
status=status.HTTP_401_UNAUTHORIZED)
elif len(parts) == 1:
return Response(dict(error='Token not found'), status=status.HTTP_401_UNAUTHORIZED)
elif len(parts) > 2:
return Response(dict(error='Authorization header must be Bearer token'),
status=status.HTTP_401_UNAUTHORIZED)
token = parts[1]
try:
res = decode_cognito_jwt(token)
except Exception:
# Fail if invalid
return Response("Invalid JWT", status=status.HTTP_401_UNAUTHORIZED) # Or HttpResponseForbidden()
else:
# Proceed with the view if valid
return view_func(request, *args, **kwargs)
return wrapped_view
CodePudding user response:
With function-based views, you don't need to use method_decorator
so:
@api_view(['PUT'])
@cognito_authenticator
def edit_post(request, post_id):
...