psycodict.grants¶
Who gets to read and write the relations psycodict creates.
Creating a search table creates several relations – the table itself, its
counts and stats tables – and a reload creates and swaps more. Something has
to decide what privileges those come into existence with, and psycodict used to
decide it in the code: SELECT to lmfdb and webserver, INSERT to
webserver, wherever those roles happened to exist. That is the LMFDB’s
deployment, not a fact about a PostgreSQL database, and it meant a new table
holding whatever you put in it was readable by two roles you may never have
heard of.
A GrantPolicy states those privileges explicitly, by relation kind.
The default policy grants nothing, so a relation is reachable only by its owner
and by whatever the cluster’s own defaults give away; LMFDBGrantPolicy()
reproduces what psycodict used to do, for the deployments that want it:
db = PostgresDatabase(grant_policy=LMFDBGrantPolicy())
A policy is authoritative for the relations psycodict applies it to: it revokes the actions it manages from the roles it names before granting, so the result is the policy and not the policy plus whatever was there before.
- class psycodict.grants.GrantPolicy(grants: dict = <factory>, missing_role: str = 'error')[source]¶
Bases:
objectThe privileges psycodict grants on the relations it creates.
INPUT:
grants– a mapping from relation kind (seeRELATION_KINDS) to a mapping from action (seeGRANT_ACTIONS) to the roles that get it. Kinds left out get nothing.missing_role– what to do when the policy names a role the cluster does not have:"error"(the default) refuses, so that a policy is never half-applied without saying so;"skip"warns and carries on, which is what a development machine without the deployment’s roles wants.
EXAMPLES:
>>> GrantPolicy({"search": {"SELECT": ("readonly",)}}) GrantPolicy(grants={'search': {'SELECT': ('readonly',)}}, missing_role='error')
- property roles¶
Every role this policy mentions.
These are the roles whose privileges psycodict manages: applying the policy revokes the managed actions from them first, so that what a relation ends up with is the policy rather than the policy plus whatever it inherited. Roles the policy does not mention are not touched.
- psycodict.grants.LMFDBGrantPolicy(missing_role='skip')[source]¶
The permissions psycodict granted before they were a policy.
SELECT to
lmfdbandwebserveron search, counts, stats and metadata relations, and INSERT towebserveron counts and stats, which the website needs in order to record the counts it computes. Backup (_oldN) tables get nothing: they hold the data the live table held before a reload, and a rename carries the live table’s privileges over to them, so the policy revokes what the live table had rather than leaving a copy of production readable by the application roles.INPUT:
missing_role– defaults to"skip", since a development database typically has neither role; pass"error"on a deployment that should have both.