Skip to content

Bovine_herd + cattle_grid

cattle_grid is meant as a layer that deals with authentication of Fediverse requests. Separating this from bovine_herd has the advantage, that one can reuse this layer for different applications.

As with a blocklist, the main modification will be specifying an authorize function when invoking BovineHerd. Alternatively one can directly use add_authorization_with_cattle_grid.

app example

This means that the simplest such app would look like

from quart import Quart
from bovine_herd import BovineHerd
from bovine_herd.server.authorize import add_authorization_with_cattle_grid


app = Quart(__name__)

BovineHerd(
    app,
    authorization_adder=add_authorization_with_cattle_grid,
)

See the cattle_grid instructions for how to configure nginx.

The new authorize function

We assume that the x-cattle-grid-requester header is passed to the bovine_herd server. If this header is set, we know that the HTTP signature was valid. All that remains to check is the digest for post requests.

Furthermore, if the header is not set, we proceed with the normal bovine_herd authorization method.

from quart import request, g

from bovine.crypto.helper import content_digest_sha256
from bovine_herd.server.authorize import add_authorization

async def authorize():
    requester = request.headers.get("x-cattle-grid-requester")

    if requester:
        if request.method.lower() == "post":
            digest = content_digest_sha256(await request.get_data())
            request_digest = request.headers.get("digest")
            request_digest = request_digest[:4].lower() + request_digest[4:]
            if digest != request_digest:
                return "unauthorized", 401

        g.retriever = requester
    else:
        return await add_authorization()