datasette icon indicating copy to clipboard operation
datasette copied to clipboard

Reconsider ensure_permissions() logic, can it be less confusing?

Open simonw opened this issue 2 years ago • 3 comments

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 returns False:

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

simonw avatar Mar 21 '22 17:03 simonw

This method here: https://github.com/simonw/datasette/blob/e627510b760198ccedba9e5af47a771e847785c9/datasette/app.py#L632-L664

simonw avatar Mar 21 '22 17:03 simonw

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.

simonw avatar Mar 21 '22 17:03 simonw

Maybe there is a better name for this method that helps emphasize its cascading nature.

simonw avatar Mar 21 '22 20:03 simonw