[PATCH 1 of 3 saem v2] [security] Fix permissions of the use_profile relation

Sylvain Thenault sylvain.thenault at logilab.fr
Thu Apr 27 10:37:18 CEST 2017


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1492789034 -7200
#      Fri Apr 21 17:37:14 2017 +0200
# Node ID 0ceefd04835e51fec6c98871aa859719e4dd8f37
# Parent  390a4f075ad402d3fc81dbb7e45f1634efa58e30
# Available At http://hg.logilab.org/review/cubes/saem_ref
#              hg pull http://hg.logilab.org/review/cubes/saem_ref -r 0ceefd04835e
[security] Fix permissions of  the use_profile relation

They should be editable depending on the permission of the associated
organization unit.

Security is set using a decorator that will be reused in later changeset.

Also, add use_profile relation to the structure that control copy, as it should
not be copied.

diff --git a/cubicweb_saem_ref/migration/0.15.3_Any.py b/cubicweb_saem_ref/migration/0.15.3_Any.py
new file mode 100644
--- /dev/null
+++ b/cubicweb_saem_ref/migration/0.15.3_Any.py
@@ -0,0 +1,1 @@
+sync_schema_props_perms('use_profile')
diff --git a/cubicweb_saem_ref/schema.py b/cubicweb_saem_ref/schema.py
--- a/cubicweb_saem_ref/schema.py
+++ b/cubicweb_saem_ref/schema.py
@@ -47,11 +47,11 @@ def publication_permissions(cls):
                        'X in_state ST, ST name "draft"'),
     )
     return cls
 
 
-def authority_permissions(cls):
+def authority_permissions_etype(cls):
     """Set __permissions__ of `cls` entity type class to ensure user can
     create/update/delete provided its authority is the same as the entity's
     authority.
     """
     cls.__permissions__ = {
@@ -61,10 +61,23 @@ def authority_permissions(cls):
         'delete': ('managers', ERQLExpression('U authority A, X authority A')),
     }
     return cls
 
 
+def authority_permissions_rdef(cls):
+    """Set __permissions__ of `cls` relation definition class to ensure user can
+    create/delete provided its authority is the same as the relation subject's
+    authority.
+    """
+    cls.__permissions__ = {
+        'read': ('managers', 'users', 'guests'),
+        'add': ('managers', RRQLExpression('U authority A, S authority A')),
+        'delete': ('managers', RRQLExpression('U authority A, S authority A')),
+    }
+    return cls
+
+
 def groups_permissions(cls):
     """Set __permissions__ of `cls` entity type class preventing modification
     when user is not in managers or users group.
     """
     cls.__permissions__ = cls.__permissions__.copy()
@@ -118,17 +131,17 @@ class Organization(EntityType):
         'delete': ('managers', ),
     }
     name = String(required=True, fulltextindexed=True, unique=True)
 
 
- at authority_permissions
+ at authority_permissions_etype
 class OrganizationUnit(WorkflowableEntityType):
     __unique_together__ = [('name', 'authority')]
     name = String(required=True, fulltextindexed=True)
 
 
- at authority_permissions
+ at authority_permissions_etype
 class Agent(WorkflowableEntityType):
     __unique_together__ = [('name', 'authority')]
     name = String(required=True, fulltextindexed=True)
 
 
@@ -433,10 +446,11 @@ publication_permissions(SEDAArchiveTrans
 
 
 simplified_profile.default = True
 
 
+ at authority_permissions_rdef
 class use_profile(RelationDefinition):
     subject = 'OrganizationUnit'
     object = 'SEDAArchiveTransfer'
     cardinality = '**'
     constraints = [RQLConstraint('S archival_role R, R name "deposit"'),
diff --git a/cubicweb_saem_ref/site_cubicweb.py b/cubicweb_saem_ref/site_cubicweb.py
--- a/cubicweb_saem_ref/site_cubicweb.py
+++ b/cubicweb_saem_ref/site_cubicweb.py
@@ -156,13 +156,14 @@ def get_store(cnx):
 # causes problem because it belongs to several graphs with different compound
 # implementation (using "container" relation or not)
 seda.GRAPH_SKIP_ETYPES.add('Activity')
 # also, the new_version_of relation should not be considered as part of the
 # graph (as for e.g. container or clone_of)
-seda.GRAPH_SKIP_RTYPES.add('new_version_of')
-Entity.cw_skip_copy_for.append(('new_version_of', 'subject'))
-Entity.cw_skip_copy_for.append(('new_version_of', 'object'))
+for rtype in ('new_version_of', 'use_profile'):
+    seda.GRAPH_SKIP_RTYPES.add(rtype)
+    Entity.cw_skip_copy_for.append((rtype, 'subject'))
+    Entity.cw_skip_copy_for.append((rtype, 'object'))
 
 
 ####################################################################################################
 # temporary monkey-patches #########################################################################
 ####################################################################################################
diff --git a/test/test_security.py b/test/test_security.py
--- a/test/test_security.py
+++ b/test/test_security.py
@@ -121,34 +121,43 @@ class NonManagerUserTC(CubicWebTC):
     def test_create_update_organizationunit_in_own_organization(self):
         with self.admin_access.cnx() as cnx:
             other_authority = testutils.authority_with_naa(cnx, name=u'other authority')
             other_unit = testutils.organization_unit(
                 cnx, u'arch', archival_roles=[u'archival'], authority=other_authority)
+            profile = testutils.setup_profile(cnx)
             cnx.commit()
+            profile.cw_adapt_to('IWorkflowable').fire_transition('publish')
+            cnx.commit()
+
             other_authority_eid = other_authority.eid
             other_unit_eid = other_unit.eid
+            profile_eid = profile.eid
 
         with self.new_access(self.login).cnx() as cnx:
+            roles = (u'archival', u'deposit')
             unit = testutils.organization_unit(
-                cnx, u'arch', archival_roles=[u'archival'], authority=self.authority_eid)
+                cnx, u'arch', archival_roles=roles, authority=self.authority_eid)
             cnx.commit()
-            unit.cw_set(name=u'archi')
+            unit.cw_set(name=u'archi',
+                        use_profile=profile_eid)
             cnx.commit()
             unit.cw_delete()
             cnx.commit()
             arecord = testutils.authority_record(cnx, name=u'arch', kind=u'authority')
             unit.cw_set(authority_record=arecord)
             cnx.commit()
 
             with self.assertUnauthorized(cnx):
                 testutils.organization_unit(
-                    cnx, u'other arch', archival_roles=[u'archival'], authority=other_authority_eid)
+                    cnx, u'other arch', archival_roles=roles, authority=other_authority_eid)
 
             other_unit = cnx.entity_from_eid(other_unit_eid)
             with self.assertUnauthorized(cnx):
                 other_unit.cw_set(name=u'archi')
             with self.assertUnauthorized(cnx):
+                other_unit.cw_set(use_profile=profile_eid)
+            with self.assertUnauthorized(cnx):
                 other_unit.cw_delete()
             with self.assertUnauthorized(cnx):
                 other_arecord = testutils.authority_record(cnx, name=u'other arch',
                                                            kind=u'authority')
                 other_unit.cw_set(authority_record=other_arecord)
diff --git a/test/unittest_entities_container.py b/test/unittest_entities_container.py
--- a/test/unittest_entities_container.py
+++ b/test/unittest_entities_container.py
@@ -93,14 +93,15 @@ class TreeTC(CubicWebTC):
 
             # ark and cwuri should not have been copied
             self.assertNotEqual(clone.ark, transfer.ark)
             self.assertNotEqual(clone.cwuri, transfer.cwuri)
 
-            # Everything else should have been copied (but other parts of the test live in the seda
+            # Everything else beside some explicitly skipped relations should
+            # have been copied (but other parts of the test live in the seda
             # cube)
-            self.assertEqual(clone.reverse_use_profile[0].eid,
-                             agent.eid)
+            self.assertEqual(clone.ark_naa[0].eid, transfer.ark_naa[0].eid)
+            self.assertEqual(len(clone.reverse_use_profile), 0)
 
 
 if __name__ == '__main__':
     import unittest
     unittest.main()


More information about the saem-devel mailing list