Package: sigauth
directory-signature-authLibrary implementing Hawk authentication scheme using a message authentication code (MAC) algorithm to provide partial HTTP request cryptographic verification.The client implementsRequestSignerto generate a secret-salted hash of the request URL and body. The secret-salt is shared with the target server.The target server implementsRequestSignatureCheckerto check the signature provided in the request header accurately describes the request's URL and request body.IfRequestSignatureCheckeraccepts the header as genuine then the request is accepted, otherwise the request is rejected.RequestSigner usagePython requestsOn the client, a signature can be generated for arequests'srequests.Request:import requests

from sigauth.utils import RequestSigner

from django.conf import settings


request_signer = RequestSigner(settings.API_SIGNATURE_SECRET)


def send_request(method, url, body):
    request = requests.Request(method=method, url=url, body=body).prepare()
    sign_request(request)
    return requests.Session().send(request)


def sign_request(request):
    headers = request_signer.get_signature_headers(
        url=request.path_url,
        body=request.body,
        method=request.method,
        content_type=request.headers.get('Content-Type'),
    )
    request.headers.update(headers)RequestSignatureChecker usageDjango Rest FrameworkThis library implements a wrapper aroundRequestSignatureCheckerfor Django Rest Framework:SignatureCheckPermissionBase. It must be sub-classed to set the secret:from sigauth import permissions

from django.conf import settings


class SignatureCheckPermission(permissions.SignatureCheckPermissionBase):
    secret = settings.SIGNATURE_SECRETOn the target server,SignatureCheckPermissioncan then be set in theDEFAULT_PERMISSION_CLASSESsetting, or on a specific DRF view'spermission_classesattribute.Django ViewOn the target server, the signature checker can be implemented on views too:from django.http import HttpResponseForbidden

from sigauth.utils import RequestSignatureChecker


api_checker = RequestSignatureChecker(settings.SIGNATURE_SECRET)


class SignatureCheckMixin:
    def dispatch(self, request, *args, **kwargs):
        if api_checker.test_signature(request) is False:
            return HttpResponseForbidden()
        return super().dispatch(request, path='', *args, **kwargs)SignatureCheckMixincan then be used on a view to reject incoming requests that have been tampered with.Note that in the above examples, the client'ssettings.API_SIGNATURE_SECRETmust be the same value as api'ssettings.SIGNATURE_SECRETMiddlewareSome services may expect every request to require signature checks. This library implements a wrapper aroundRequestSignatureCheckerfor Django middleware to facilitate this:SignatureCheckMiddlewareBase. It must be sub-classed to set the secret:from sigauth.middleware import SignatureCheckMiddlewareBase

from django.conf import settings

class SignatureCheckMiddleware(SignatureCheckMiddlewareBase):
    secret = settings.SIGNATURE_SECRETSignatureCheckMiddlewarecan then be added to theMIDDLEWAREsetting (orMIDDLEWARE_CLASSESif using Django < 2). SetSIGAUTH_URL_NAMES_WHITELISTsettings to a list of url names that should be excluded from checks.Installationpipinstall-egit+https://git@github.com/uktrade/directory-signature-auth.git@v1.0.0#egg=directory-signature-authDevelopment$ git clone https://github.com/uktrade/directory-signature-auth
$ cd directory-signature-auth
$ makePublish to PyPIThe package should be published to PyPI on merge to master. If you need to do it locally then get the credentials from rattic and add the environment variables to your host machine:SettingDIRECTORY_PYPI_USERNAMEDIRECTORY_PYPI_PASSWORDThen run the following command:make publish