loom.core.repository.sqlalchemy.rls.integrity

Checks that the guard in the database is one this release of loom shipped, unaltered.

Everything here reads the catalogue, which every role can read, so the application user runs it at startup, the bootstrap runs it inside its own transaction and verify runs it with any connection. The catalogue of the guard is compared, category by category, with the digests pinned for the revision its functions identify; owners are compared exactly with the guard schema’s owner, which must also own both event triggers; every grant and every function setting is compared exactly. Only the configuration row needs a privileged reader; verify checks it.

Functions

_catalog_parameters(guard, kinds)

_guard_parameters(guard)

_lines(rows)

_minimum(minimum)

_protection_problems(row, table)

_revision(number)

access_problems(rows, guard, owner)

Compare every grant and every function setting of the guard exactly.

canonical_policies(privileges)

The policy names the guard creates for a scoped table with privileges.

catalog_problems(lines, guard)

Compare each catalogue category with the revision its functions identify.

guard_problems(connection, guard, owner[, ...])

Return how the guard guard differs from a released one; empty when it matches.

owner_problems(rows, installer)

Every guard object must belong to the guard schema's owner, and that to installer.

require_guard_revision(connection, guard, *)

Refuse to call a guard below minimum, by default the minimum compatible revision.

require_guard_revision_sync(connection, guard, *)

The synchronous require_guard_revision(), for the migration runners.

require_revision(number, guard, *, minimum)

Refuse a guard this release does not know or one below minimum.

revision_of(functions_digest)

The released revision whose functions digest is functions_digest, if any.

startup_problems(connection, guard, scoped)

Everything the application user can check at startup, guard and scoped tables.

table_problems(connection, guard, schema, scoped)

Compare every scoped model table with its canonical protection in the catalogue.

Classes

Problem(check, subject, expected, actual)

One way the installed guard, or a scoped table, differs from what loom expects.

SyncExecutor(*args, **kwargs)

A synchronous connection, or the bind Alembic hands an operation.

class loom.core.repository.sqlalchemy.rls.integrity.Problem(check, subject, expected, actual)[source]

Bases: object

One way the installed guard, or a scoped table, differs from what loom expects.

Parameters:
async loom.core.repository.sqlalchemy.rls.integrity.guard_problems(connection, guard, owner, installer=None)[source]

Return how the guard guard differs from a released one; empty when it matches.

owner is the application schema’s owner role, the only grantee the guard knows. With installer the guard’s owner must be that role.

Parameters:
  • connection (sqlalchemy.ext.asyncio.AsyncConnection)

  • guard (str)

  • owner (str)

  • installer (str | None)

Return type:

list[Problem]

async loom.core.repository.sqlalchemy.rls.integrity.startup_problems(connection, guard, scoped)[source]

Everything the application user can check at startup, guard and scoped tables.

Parameters:
Return type:

list[Problem]

async loom.core.repository.sqlalchemy.rls.integrity.table_problems(connection, guard, schema, scoped)[source]

Compare every scoped model table with its canonical protection in the catalogue.

Parameters:
Return type:

list[Problem]

loom.core.repository.sqlalchemy.rls.integrity.canonical_policies(privileges)[source]

The policy names the guard creates for a scoped table with privileges.

Parameters:

privileges (Iterable[Privilege])

Return type:

set[str]

loom.core.repository.sqlalchemy.rls.integrity.revision_of(functions_digest)[source]

The released revision whose functions digest is functions_digest, if any.

Parameters:

functions_digest (str)

Return type:

int | None

loom.core.repository.sqlalchemy.rls.integrity.require_revision(number, guard, *, minimum)[source]

Refuse a guard this release does not know or one below minimum.

Raises:

ConfigError – Naming the guard and what to run.

Parameters:
  • number (int | None)

  • guard (str)

  • minimum (int)

Return type:

None

async loom.core.repository.sqlalchemy.rls.integrity.require_guard_revision(connection, guard, *, minimum=None)[source]

Refuse to call a guard below minimum, by default the minimum compatible revision.

Raises:

ConfigError – When the guard is unknown or its revision is pending.

Parameters:
  • connection (sqlalchemy.ext.asyncio.AsyncConnection)

  • guard (str)

  • minimum (int | None)

Return type:

None

class loom.core.repository.sqlalchemy.rls.integrity.SyncExecutor(*args, **kwargs)[source]

Bases: Protocol

A synchronous connection, or the bind Alembic hands an operation.

loom.core.repository.sqlalchemy.rls.integrity.require_guard_revision_sync(connection, guard, *, minimum=None)[source]

The synchronous require_guard_revision(), for the migration runners.

Raises:

ConfigError – When the guard is unknown or its revision is pending.

Parameters:
Return type:

None

loom.core.repository.sqlalchemy.rls.integrity.catalog_problems(lines, guard)[source]

Compare each catalogue category with the revision its functions identify.

Parameters:
Return type:

list[Problem]

loom.core.repository.sqlalchemy.rls.integrity.owner_problems(rows, installer)[source]

Every guard object must belong to the guard schema’s owner, and that to installer.

Parameters:
Return type:

list[Problem]

loom.core.repository.sqlalchemy.rls.integrity.access_problems(rows, guard, owner)[source]

Compare every grant and every function setting of the guard exactly.

Parameters:
Return type:

list[Problem]