Is Python Webhook example outdated?

Hey, I’m following the next example from official docs.

I’m using postman to create the Webhook I’m using something like this

{
    "data": {
        "filters": [
            {
                "action": "added",
                "resource_type": "task"
            }
        ],
        "resource": "PROJECT_GID",
        "target": "https://XYZ.ngrok-free.app/create_task/"
    }
}

My webhook server is a django project running with python3. This is my viewset

class CreateAsanaTaskWebhookHandler(CreateAPIView):
    """ Handle Asana webhook to create a new task. """
    serializer_class = AsanaTaskSerializer
    secret_name = 'Create AsanaTask Webhook Secret'
    permission_classes = [AllowAny]

    def post(self, request, *args, **kwargs):
        if 'X-Hook-Secret' in request.headers:
            secret = request.headers['X-Hook-Secret']
            AsanaWebHookSecret.objects.update_or_create(
                name=self.secret_name,
                defaults={
                    'secret': secret,
                },
            )

            response = Response(status=200)
            response['X-Hook-Secret'] = secret
            return response

        if 'X-Hook-Signature' in request.headers:
            webhook_secret = AsanaWebHookSecret.objects.filter(
                name=self.secret_name
            ).first()

            if not webhook_secret:
                return Response(
                    data={'detail': 'X-Hook-Secret not found.'},
                    status=400,
                )

            secret = webhook_secret.secret
            signature = hmac.new(
                secret.encode('ascii', 'ignore'),
                msg=str(request.data).encode('ascii', 'ignore'),
                digestmod=hashlib.sha256
            ).hexdigest()

            if not hmac.compare_digest(
                signature.encode('ascii', 'ignore'),
                request.headers["X-Hook-Signature"].encode('ascii', 'ignore')
            ):
                return Response(
                    data={'detail': 'Invalid X-Hook-Signature.'},
                    status=400,
                )

            print(request.data)
        return Response(status=400)

I have the same problem described in this issue in github WebHook: Python3 - TypeError: Unicode-objects must be encoded before hashing · Issue #24 · Asana/devrel-examples · GitHub
But the real problem are on these lines

            if not hmac.compare_digest(
                signature.encode('ascii', 'ignore'),
                request.headers["X-Hook-Signature"].encode('ascii', 'ignore')
            ):
                return Response(
                    data={'detail': 'Invalid X-Hook-Signature.'},
                    status=400,
                )

For some reason this block of code is executed even if the request comes from Asana. I really appreciate some help I think I’m missing something important.
Please ignore the django stuffs.

The example is not outdated, it is just different from yours. You are using django rest framework where the request.data is a dict object, while it should be a byte array or alike. So you should just use request.body directly and no need to encode it.

1 Like