[PATCH 1 of 1 sherpa V2] [schema] Implement security for ArchiveTransfer, AuthorityRecord and ConceptScheme

Sylvain Thenault sylvain.thenault at logilab.fr
Wed Mar 8 11:40:55 CET 2017


# HG changeset patch
# User Philippe Pepiot <philippe.pepiot at logilab.fr>
# Date 1487782953 -3600
#      Wed Feb 22 18:02:33 2017 +0100
# Node ID f907c3952a6153311a657546c6b686e118c184b9
# Parent  bf3fa11e713283497dbc332a719e579b5205b336
[schema] Implement security for ArchiveTransfer, AuthorityRecord and ConceptScheme

For now, we need to setup ConceptScheme compound security since it's not done
yet by the skos cube, unlike eac and seda cubes.

Related to #16684441

diff --git a/cubicweb_sherpa/schema.py b/cubicweb_sherpa/schema.py
new file mode 100644
--- /dev/null
+++ b/cubicweb_sherpa/schema.py
@@ -0,0 +1,31 @@
+# copyright 2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr -- mailto:contact at logilab.fr
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# This program 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from cubes.skos.schema import ConceptScheme
+
+ConceptScheme.__permissions__ = {
+    'read': ('managers', 'users', 'guests'),
+    'add': ('managers',),
+    'update': ('managers',),
+    'delete': ('managers',),
+}
+
+
+def post_build_callback(schema):
+    from cubicweb_compound import CompositeGraph, lib
+    graph = CompositeGraph(schema)
+    lib.graph_set_etypes_update_permissions(schema, graph, 'ConceptScheme')
+    lib.graph_set_write_rdefs_permissions(schema, graph, 'ConceptScheme')
diff --git a/dev-requirements.txt b/dev-requirements.txt
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,1 +1,2 @@
 pytest
+http://hg.logilab.org/review/cubes/compound/archive/tip.tar.bz2#egg=cubicweb-compound
diff --git a/test/test_security.py b/test/test_security.py
new file mode 100644
--- /dev/null
+++ b/test/test_security.py
@@ -0,0 +1,103 @@
+# copyright 2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr -- mailto:contact at logilab.fr
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# This program 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""cubicweb-sherpa security tests"""
+
+from contextlib import contextmanager
+
+from cubicweb import Unauthorized
+from cubicweb.devtools.testlib import CubicWebTC
+
+
+class SecurityTC(CubicWebTC):
+
+    @contextmanager
+    def assertUnauthorized(self, cnx):
+        with self.assertRaises(Unauthorized) as cm:
+            yield cm
+            cnx.commit()
+        cnx.rollback()
+
+    def setUp(self):
+        super(SecurityTC, self).setUp()
+        with self.admin_access.cnx() as cnx:
+            self.create_user(cnx, 'bob')
+            self.create_user(cnx, 'alice')
+
+    def assertOwnershipBasedAccess(self, etype, to_test_attribute):
+        # alice can read bob entity, but not update nor delete
+        with self.new_access('alice').cnx() as cnx:
+            entity = cnx.find(etype).one()
+            with self.assertUnauthorized(cnx):
+                entity.cw_set(**{to_test_attribute: u'abcd'})
+                cnx.commit()
+            with self.assertUnauthorized(cnx):
+                entity.cw_delete()
+                cnx.commit()
+        # unless explicitly authorized using owned_by relation
+        with self.new_access('bob').cnx() as cnx:
+            entity = cnx.find(etype).one()
+            entity.cw_set(owned_by=cnx.find('CWUser', login='alice').one())
+            cnx.commit()
+        with self.new_access('alice').cnx() as cnx:
+            entity = cnx.find(etype).one()
+            entity.cw_set(**{to_test_attribute: u'abcd'})
+            cnx.commit()
+            entity.cw_delete()
+            cnx.commit()
+
+    def test_add_read_update_delete_record(self):
+        with self.new_access('bob').cnx() as cnx:
+            agent_kind = cnx.find('AgentKind', name=u'person').one()
+            record = cnx.create_entity('AuthorityRecord', agent_kind=agent_kind)
+            cnx.create_entity('NameEntry', parts=u'bob notice', form_variant=u'authorized',
+                              name_entry_for=record)
+            cnx.commit()
+
+        self.assertOwnershipBasedAccess('AuthorityRecord', 'isni')
+
+    def test_add_read_update_delete_transfer(self):
+        with self.new_access('bob').cnx() as cnx:
+            cnx.create_entity('SEDAArchiveTransfer', title=u'goldorak go')
+            cnx.commit()
+
+        self.assertOwnershipBasedAccess('SEDAArchiveTransfer', 'title')
+
+    def test_add_read_update_delete_schemes(self):
+        with self.new_access('bob').cnx() as cnx:
+            with self.assertUnauthorized(cnx):
+                cnx.create_entity('ConceptScheme', title=u'goldorak')
+
+        with self.admin_access.cnx() as cnx:
+            scheme = cnx.create_entity('ConceptScheme', title=u'goldorak')
+            concept = scheme.add_concept(u'fulguropoint')
+            cnx.commit()
+
+        with self.new_access('bob').cnx() as cnx:
+            scheme = cnx.find('ConceptScheme').one()
+            with self.assertUnauthorized(cnx):
+                scheme.cw_set(title=u'hop')
+            with self.assertUnauthorized(cnx):
+                scheme.add_concept(u'fulguropoint')
+            concept = cnx.find('Concept').one()
+            with self.assertUnauthorized(cnx):
+                concept.cw_delete()
+            with self.assertUnauthorized(cnx):
+                scheme.cw_delete()
+
+
+if __name__ == '__main__':
+    import unittest
+    unittest.main()



More information about the saem-devel mailing list