datasette
datasette copied to clipboard
Reconsider ensure_permissions() logic, can it be less confusing?
Updated documentation: https://github.com/simonw/datasette/blob/e627510b760198ccedba9e5af47a771e847785c9/docs/internals.rst#await-ensure_permissionsactor-permissions
This method allows multiple permissions to be checked at onced. It raises a
datasette.Forbidden
exception if any of the checks are denied before one of them is explicitly granted.This is useful when you need to check multiple permissions at once. For example, an actor should be able to view a table if either one of the following checks returns
True
or not a single one of them returnsFalse
:That's pretty hard to understand! I'm going to open a separate issue to reconsider if this is a useful enough abstraction given how confusing it is.
Originally posted by @simonw in https://github.com/simonw/datasette/issues/1675#issuecomment-1074177827
This method here: https://github.com/simonw/datasette/blob/e627510b760198ccedba9e5af47a771e847785c9/datasette/app.py#L632-L664
When looking at this code earlier I assumed that the following would check each permission in turn and fail if any of them failed:
await self.ds.ensure_permissions(
request.actor,
[
("view-table", (database, table)),
("view-database", database),
"view-instance",
]
)
But it's not quite that simple: if any of them fail, it fails... but if an earlier one returns True
the whole stack passes even if there would have been a failure later on!
If that is indeed the right abstraction, I need to work to make the documentation as clear as possible.
Maybe there is a better name for this method that helps emphasize its cascading nature.