Skip to content

Commit

Permalink
access: access-control helpers improvements
Browse files Browse the repository at this point in the history
* Creates the AuthenticatedNeed.

* Adds allow_if_no_permissions to PermissionSet.

Signed-off-by: Nicolas Harraudeau <nicolas.harraudeau@cern.ch>
  • Loading branch information
Nicolas Harraudeau committed Nov 8, 2016
1 parent e49448c commit c96075c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 20 deletions.
21 changes: 5 additions & 16 deletions b2share/modules/access/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,42 +30,31 @@
from werkzeug.local import LocalProxy
from flask_principal import AnonymousIdentity

from .permissions import AuthenticatedNeed


current_flask_security = LocalProxy(
lambda: current_app.extensions['security']
)


def _load_permissions_on_identity_loaded(sender, identity):
"""Load the user permissions when his identity is loaded."""
# from b2share.modules.records.permissions import \
# read_open_access_record_need
# if the user is not anonymous
if current_user.get_id() is not None:
# Set the identity user object
identity.user = current_user

# Add the permission to create draft deposits in any community
# Add the need provided to authenticated users
identity.provides.add(
ParameterizedActionNeed('create-deposit-draft', None)
AuthenticatedNeed
)
# Add the permission to read open access records
# identity.provides.add(
# read_open_access_record_need
# )

def _register_anonymous_loader():
"""Register the Anonymous Identity loader."""
# from b2share.modules.records.permissions import \
# read_open_access_record_need

def anonymous_idendity_loader():
identity = AnonymousIdentity()
# Here we can add configurable permissions to anonymous users.

# all anonymous users can read open access records
# identity.provides.add(
# read_open_access_record_need
# )
return identity
current_flask_security.principal.identity_loader(anonymous_idendity_loader)

Expand Down
17 changes: 13 additions & 4 deletions b2share/modules/access/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

"""B2Share generic permissions."""

from flask_principal import Permission
from flask_principal import Permission, Need
from invenio_access.permissions import DynamicPermission


Expand All @@ -41,11 +41,19 @@
"""Permission that always deny an access."""


AuthenticatedNeed = Need('authenticated', True)
"""Need provided by any authenticated user."""


class StrictDynamicPermission(DynamicPermission):
"""Stricter DynamicPermission.
It adds the given needs to the returned needs instead of using only
those found in the database.
This has two effects:
- Identities can also provide aneed without using the database.
- The permission is not given even if there are no needs in the
database. Thus the action is not allowed by default.
"""
def __init__(self, *needs):
self.explicit_excludes = set()
Expand All @@ -67,11 +75,12 @@ def excludes(self):
class PermissionSet(Permission):
"""Abstract permissions combining multiple permissions."""

def __init__(self, *permissions):
def __init__(self, *permissions, allow_if_no_permissions=False):
"""A set of set of permissions, all of which must be allow the
identity to have access.
"""
self.permissions = set(permissions)
self.allow_if_no_permissions = allow_if_no_permissions

def allows(self, identity):
raise NotImplementedError()
Expand Down Expand Up @@ -111,7 +120,7 @@ def allows(self, identity):
for permission in self.permissions:
if not permission.allows(identity):
return False
return True
return len(self.permissions) > 0 or self.allow_if_no_permissions


class OrPermissions(PermissionSet):
Expand All @@ -132,4 +141,4 @@ def allows(self, identity):
for permission in self.permissions:
if permission.allows(identity):
return True
return False
return len(self.permissions) == 0 and self.allow_if_no_permissions

0 comments on commit c96075c

Please sign in to comment.