From 5f086b84eb5d8dbfccb217e7ff76aec70f6f981d Mon Sep 17 00:00:00 2001 From: Christos Topaloudis Date: Mon, 30 Jul 2018 14:49:08 +0200 Subject: [PATCH] Attempt to implement #26 --- invenio_circulation/config.py | 3 ++ invenio_circulation/permissions.py | 68 ++++++++++++++++++++++++++++++ setup.py | 1 + tests/test_permissions.py | 43 +++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 invenio_circulation/permissions.py create mode 100644 tests/test_permissions.py diff --git a/invenio_circulation/config.py b/invenio_circulation/config.py index d3972a9..260ebb7 100644 --- a/invenio_circulation/config.py +++ b/invenio_circulation/config.py @@ -10,6 +10,7 @@ from .api import Loan from .links import loan_links_factory +from .permissions import circulation_permission_factory from .transitions.transitions import ItemOnLoanToItemInTransitHouse, \ ItemOnLoanToItemReturned, PendingToItemAtDesk, \ PendingToItemInTransitPickup @@ -31,6 +32,8 @@ _CIRCULATION_ACTION_LINKS_FACTORY = loan_links_factory """.""" +CIRCULATION_PERMISSION_FACTORY = circulation_permission_factory +""".""" CIRCULATION_STATES_ITEM_AVAILABLE = ['ITEM_RETURNED'] """.""" diff --git a/invenio_circulation/permissions.py b/invenio_circulation/permissions.py new file mode 100644 index 0000000..3b975c6 --- /dev/null +++ b/invenio_circulation/permissions.py @@ -0,0 +1,68 @@ +# This file is part of Invenio. +# Copyright (C) 2017 CERN. +# +# Invenio is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# Invenio is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Invenio; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307, USA. +# +# In applying this license, CERN does not +# waive the privileges and immunities granted to it by virtue of its status +# as an Intergovernmental Organization or submit itself to any jurisdiction. + +"""Access control for Circulation.""" + + +from __future__ import absolute_import, print_function + +from flask_security import current_user + + +class CirculationPermission(object): + """Circulation permission.""" + + create_actions = ['create'] + read_actions = ['read'] + + def __init__(self, record, func, user): + """Initialize a permission object.""" + self.record = record + self.func = func + self.user = user or current_user + + def can(self): + """Determine access.""" + return self.func(self.user, self.record) + + @classmethod + def create(cls, record, action, user=None): + """Create a circulation permission.""" + if action in cls.create_actions: + return cls(record, allow, user) + else: + return cls(record, deny, user) + + +def deny(user, record): + """Deny access.""" + return False + + +def allow(user, record): + """Allow access.""" + return True + + +def circulation_permission_factory(record=None, action=None): + """Circulation permission factory.""" + return CirculationPermission.create(record, action) diff --git a/setup.py b/setup.py index d43a5e0..c73698b 100644 --- a/setup.py +++ b/setup.py @@ -73,6 +73,7 @@ install_requires = [ 'Flask-BabelEx>=0.9.3', + 'flask-security>=3.0.0', 'invenio-base>=1.0.1', 'invenio-logging>=1.0.0', 'invenio-pidstore>=1.0.0', diff --git a/tests/test_permissions.py b/tests/test_permissions.py new file mode 100644 index 0000000..12b0cdd --- /dev/null +++ b/tests/test_permissions.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# +# This file is part of CDS. +# Copyright (C) 2015, 2016, 2018 CERN. +# +# CDS is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# CDS is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with CDS; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307, USA. +# +# In applying this license, CERN does not +# waive the privileges and immunities granted to it by virtue of its status +# as an Intergovernmental Organization or submit itself to any jurisdiction. + +"""Test access control package.""" + +import uuid + +import pytest +from invenio_records.api import Record + +from invenio_circulation.permissions import circulation_permission_factory + + +@pytest.mark.parametrize('access,action,is_allowed', [ + ({'foo': 'bar'}, 'create', True), + ({'foo': 'bar'}, 'read', True), +]) +def test_access(db, access, action, is_allowed): + """Test access control.""" + record = Record.create(access, id_=uuid.uuid4()) + factory = circulation_permission_factory(record, action) + assert factory.can()