[PATCH 1 of 3 saem_ref] [schema] Set proper permissions on Activity and its relations

Sylvain Thenault sylvain.thenault at logilab.fr
Wed Mar 22 10:57:26 CET 2017


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1490107218 -3600
#      Tue Mar 21 15:40:18 2017 +0100
# Node ID 4ba8b2fffa85e8006b75758a4dddfa62d31a331d
# Parent  87fd946c64f9d75eb5767666eb590b731938a9ee
[schema] Set proper permissions on Activity and its relations

We would expect them to be only addable/modifyable by hooks but this is not yet
possible because the eac cube uses activity as part of its business model. We
may still securize update/deletion and the associated_with relation which is not
used by the the eac cube.

Notice those permissions have been impacted by 03590369788c though they were already
incorrect before, should be now almost ok beside the above warning.

Related to extranet #3101354

diff --git a/cubicweb_saem_ref/migration/0.15.0_Any.py b/cubicweb_saem_ref/migration/0.15.0_Any.py
--- a/cubicweb_saem_ref/migration/0.15.0_Any.py
+++ b/cubicweb_saem_ref/migration/0.15.0_Any.py
@@ -1,2 +1,5 @@
+for ertype in ('Activity', 'associated_with', 'generated', 'used'):
+    sync_schema_props_perms(ertype)
+
 add_relation_definition('Activity', 'generated', 'SEDAArchiveTransfer')
 add_relation_definition('Activity', 'used', 'SEDAArchiveTransfer')
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
@@ -24,10 +24,11 @@ from cubicweb.schema import (RO_ATTR_PER
                              RQLConstraint, RQLVocabularyConstraint, WorkflowableEntityType,
                              make_workflowable)
 from cubicweb.schemas.base import ExternalUri, EmailAddress
 
 from cubes.skos.schema import ConceptScheme
+from cubicweb_prov import schema as prov
 from cubicweb_eac.schema import AuthorityRecord, NameEntry
 from cubicweb_seda.schema import simplified_profile
 from cubicweb_seda.schema.seda2 import SEDAArchiveTransfer
 from cubicweb_compound import utils
 
@@ -153,15 +154,10 @@ class agent_user(RelationDefinition):
         RQLConstraint('NOT EXISTS(O authority A) '
                       'OR EXISTS(O authority B, S authority B)'),
     ]
 
 
-class associated_with(RelationDefinition):
-    subject = 'Activity'
-    object = 'CWUser'
-
-
 class _authority_record(RelationDefinition):
     __permissions__ = {
         'read': ('managers', 'users', 'guests'),
         'add': ('managers',),
         'delete': ('managers',),
@@ -280,20 +276,54 @@ class related_concept_scheme(RelationDef
     object = 'ConceptScheme'
     cardinality = '**'
     description = _('concept schemes used by the agent')
 
 
+# PROV #########################################################################
+
+# we have to let addition permission to managers/users but eac use them for user-land imports but
+# empty permission would be better because those are expected to be set by hooks. We could probably
+# change eac import to by-pass security for activities?
+
 class generated(RelationDefinition):
+    __permissions__ = {
+        'read': ('managers', 'users', 'guests'),
+        'add': ('managers', 'users'),
+        'delete': (),
+    }
     subject = 'Activity'
     object = ('Concept', 'ConceptScheme', 'SEDAArchiveTransfer')
 
 
 class used(RelationDefinition):
+    __permissions__ = {
+        'read': ('managers', 'users', 'guests'),
+        'add': ('managers', 'users'),
+        'delete': (),
+    }
     subject = 'Activity'
     object = ('Concept', 'ConceptScheme', 'SEDAArchiveTransfer')
 
 
+class associated_with(RelationDefinition):
+    __permissions__ = {
+        'read': ('managers', 'users', 'guests'),
+        'add': ('managers', 'users'),
+        'delete': (),
+    }
+    subject = 'Activity'
+    object = 'CWUser'
+
+
+prov.Activity.__permissions__ = {
+    'read': ('managers', 'users', 'guests'),
+    'add': ('managers', 'users'),
+    'update': (),
+    'delete': (),
+}
+
+
 # ARK ##########################################################################
 
 class ark(RelationDefinition):
     __permissions__ = RO_ATTR_PERMS
     subject = (
@@ -399,5 +429,17 @@ def post_build_callback(schema):
     for rtype in ('in_scheme', 'broader_concept', 'label_of'):
         for rdef in schema[rtype].rdefs.values():
             rdef.set_action_permissions('add', ('managers', 'users'))
             if rtype == 'label_of':
                 rdef.set_action_permissions('delete', ('managers', 'users'))
+
+    # reset permissions, unexpectedly changed by seda's post_build_callback
+    def sync_perms(erdef, permissions):
+        for action, permissions in permissions.items():
+            erdef.set_action_permissions(action, permissions)
+
+    sync_perms(schema['Activity'], prov.Activity.__permissions__)
+    for rdef_def in (generated, used, associated_with):
+        objtypes = rdef_def.object if isinstance(rdef_def.object, tuple) else (rdef_def.object,)
+        for objtype in objtypes:
+            rdef = schema[rdef_def.__name__].rdefs[(rdef_def.subject, objtype)]
+            sync_perms(rdef, rdef_def.__permissions__)
diff --git a/test/test_security.py b/test/test_security.py
--- a/test/test_security.py
+++ b/test/test_security.py
@@ -75,10 +75,29 @@ class NonManagerUserTC(CubicWebTC):
         with self.new_access(self.login).cnx() as cnx:
             with self.assertUnauthorized(cnx):
                 testutils.organization_unit(
                     cnx, u'arch', archival_roles=(u'archival', ))
 
+    def test_cannot_modify_activities(self):
+        with self.new_access(self.login).cnx() as cnx:
+            arecord = testutils.authority_record(cnx, name=u'a')
+            cnx.commit()
+
+            activity = arecord.reverse_used[0]
+
+            with self.assertUnauthorized(cnx):
+                activity.cw_set(description=u'hacked')
+
+            with self.assertUnauthorized(cnx):
+                activity.cw_set(associated_with=cnx.find('CWUser', login='admin').one())
+
+            with self.assertUnauthorized(cnx):
+                activity.cw_set(generated=None)
+
+            with self.assertUnauthorized(cnx):
+                activity.cw_delete()
+
 
 class ManagerUserTC(CubicWebTC):
     """Tests checking that a user in "managers" group only can do things.
 
     Most of the times, we do not call any assertion method and only rely on no


More information about the saem-devel mailing list