You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In my Flask application, I use class based Views. All views are derived from a base class.
The base class does not have a registered url rule and never receives requests directly.
My desire was to put an "Always Deny" permission on this base class to force any derived view
to explicitly declare permissions, thus creating a "safe by default" pattern.
I was surprised to find that Flask-Principal does not seem to have any (convenient) way of creating such a Permission.
The fundamental problem is that a Permission() without any Needs defaults to 'allow'
This is a little unintuitive given "A Permission is a set of requirements, any of which should be present for access to a resource."
But the chosen design is defensible, so probably an extra note in the documentation is sufficient to specify this corner case.
What is more problematic is that a Denial() without any Needs ALSO defaults to 'allow'. So we have a situation where
Permission() means 'allow' and Denial() also means 'allow'.
PROPOSAL
Part 1) Allow the default disposition (i.e. if permission.perms is an empty set) to be specified.
e.g.
class Permission(object):
def __init__(self, *needs, default_permit=True):
self.perms = {n: True for n in needs}
self.default = default_permit
def allows(self, identity):
if self.needs and not self.needs.intersection(identity.provides):
return False
if self.excludes and self.excludes.intersection(identity.provides):
return False
if self.perms:
return True
return self.default
Part 2) Denial() should default to 'deny'.
This is more a restoration of sanity rather than a necessity. The change of Part 1, makes this less necessary.
Alternately, This change would make the change in Part 1 unnecessary as Denial() would be the missing "Always deny" permission.
e.g.
class Denial(Permission):
def __init__(self, *needs, default_permit=False): # default_permit=True would be backward compatible
This is a potentially breaking change. However.
The documentation does not say what will happen in this case.
There are no instances of Denial() in the unit tests (There ARE instances of Permission() in the unit tests)
The text was updated successfully, but these errors were encountered:
In my Flask application, I use class based Views. All views are derived from a base class.
The base class does not have a registered url rule and never receives requests directly.
My desire was to put an "Always Deny" permission on this base class to force any derived view
to explicitly declare permissions, thus creating a "safe by default" pattern.
I was surprised to find that Flask-Principal does not seem to have any (convenient) way of creating such a Permission.
The fundamental problem is that a Permission() without any Needs defaults to 'allow'
This is a little unintuitive given "A Permission is a set of requirements, any of which should be present for access to a resource."
But the chosen design is defensible, so probably an extra note in the documentation is sufficient to specify this corner case.
What is more problematic is that a Denial() without any Needs ALSO defaults to 'allow'. So we have a situation where
Permission() means 'allow' and Denial() also means 'allow'.
PROPOSAL
Part 1) Allow the default disposition (i.e. if permission.perms is an empty set) to be specified.
e.g.
Part 2) Denial() should default to 'deny'.
This is more a restoration of sanity rather than a necessity. The change of Part 1, makes this less necessary.
Alternately, This change would make the change in Part 1 unnecessary as Denial() would be the missing "Always deny" permission.
e.g.
This is a potentially breaking change. However.
The documentation does not say what will happen in this case.
There are no instances of Denial() in the unit tests (There ARE instances of Permission() in the unit tests)
The text was updated successfully, but these errors were encountered: