Commit 9144b733 authored by Aurelien Campeas's avatar Aurelien Campeas
Browse files

"add" permission for attributes (to distinguish from "update")

Closes #149216.
parent 7e385dc431ac
...@@ -9,6 +9,7 @@ ChangeLog for yams ...@@ -9,6 +9,7 @@ ChangeLog for yams
* add package attribute on (etype, rtype, rdef) (#69392) * add package attribute on (etype, rtype, rdef) (#69392)
* [schema2sql] provide an index name computation function for unique * [schema2sql] provide an index name computation function for unique
together constraints (#189299) together constraints (#189299)
* an "add" permission on attributes
2013-06-28 -- 0.38.0 2013-06-28 -- 0.38.0
* [xy] fail assertion only if existing prefix is being changed (#139999) * [xy] fail assertion only if existing prefix is being changed (#139999)
......
...@@ -116,14 +116,14 @@ def register_base_types(schema): ...@@ -116,14 +116,14 @@ def register_base_types(schema):
edef = EntityType(name=etype) edef = EntityType(name=etype)
schema.add_entity_type(edef) schema.add_entity_type(edef)
# XXX use a "frozendict"
DEFAULT_RELPERMS = {'read': ('managers', 'users', 'guests',), DEFAULT_RELPERMS = {'read': ('managers', 'users', 'guests',),
'delete': ('managers', 'users'), 'delete': ('managers', 'users'),
'add': ('managers', 'users',)} 'add': ('managers', 'users',)}
DEFAULT_ATTRPERMS = {'read': ('managers', 'users', 'guests',), DEFAULT_ATTRPERMS = {'read': ('managers', 'users', 'guests',),
'update': ('managers', 'owners'), 'add': ('managers', 'users'),
} 'update': ('managers', 'owners')}
class Relation(object): class Relation(object):
"""Abstract class which have to be defined before the metadefinition """Abstract class which have to be defined before the metadefinition
...@@ -258,7 +258,6 @@ class EntityType(Definition): ...@@ -258,7 +258,6 @@ class EntityType(Definition):
#: .. automethod:: EntityType.get_relations #: .. automethod:: EntityType.get_relations
__metaclass__ = metadefinition __metaclass__ = metadefinition
# XXX use a "frozendict"
__permissions__ = { __permissions__ = {
'read': ('managers', 'users', 'guests',), 'read': ('managers', 'users', 'guests',),
'update': ('managers', 'owners',), 'update': ('managers', 'owners',),
......
...@@ -51,6 +51,8 @@ def check_permission_definitions(schema): ...@@ -51,6 +51,8 @@ def check_permission_definitions(schema):
assert isinstance(groups, tuple), \ assert isinstance(groups, tuple), \
('permission for action %s of %s isn\'t a tuple as ' ('permission for action %s of %s isn\'t a tuple as '
'expected' % (action, schema)) 'expected' % (action, schema))
if schema.final:
schema.advertise_new_add_permission()
for action in schema.ACTIONS: for action in schema.ACTIONS:
assert action in schema.permissions, \ assert action in schema.permissions, \
'missing expected permissions for action %s for %s' % (action, schema) 'missing expected permissions for action %s for %s' % (action, schema)
...@@ -207,6 +209,10 @@ class EntitySchema(PermissionMixIn, ERSchema): ...@@ -207,6 +209,10 @@ class EntitySchema(PermissionMixIn, ERSchema):
self.subjrels = rehash(self.subjrels) self.subjrels = rehash(self.subjrels)
self.objrels = rehash(self.objrels) self.objrels = rehash(self.objrels)
def advertise_new_add_permission(self):
pass
# schema building methods ################################################# # schema building methods #################################################
def add_subject_relation(self, rschema): def add_subject_relation(self, rschema):
...@@ -828,7 +834,7 @@ class RelationDefinitionSchema(PermissionMixIn): ...@@ -828,7 +834,7 @@ class RelationDefinitionSchema(PermissionMixIn):
@property @property
def ACTIONS(self): def ACTIONS(self):
if self.rtype.final: if self.rtype.final:
return ('read', 'update') return ('read', 'add', 'update')
else: else:
return ('read', 'add', 'delete') return ('read', 'add', 'delete')
...@@ -849,6 +855,26 @@ class RelationDefinitionSchema(PermissionMixIn): ...@@ -849,6 +855,26 @@ class RelationDefinitionSchema(PermissionMixIn):
def as_triple(self): def as_triple(self):
return (self.subject, self.rtype, self.object) return (self.subject, self.rtype, self.object)
def advertise_new_add_permission(self):
"""handle backward compatibility with pre-add permissions
* if the update permission was () [empty tuple], use the
default attribute permissions for `add`
* else copy the `update` rule for `add`
"""
if not 'add' in self.permissions:
from yams.buildobjs import DEFAULT_ATTRPERMS
if self.permissions['update'] == ():
defaultaddperms = DEFAULT_ATTRPERMS['add']
else:
defaultaddperms = self.permissions['update']
self.permissions['add'] = defaultaddperms
warnings.warn('[yams 0.39] %s: new "add" permissions on attribute '
'set to %s by default, but you must make it explicit' %
(self, defaultaddperms), DeprecationWarning)
@classmethod @classmethod
def rproperty_defs(cls, desttype): def rproperty_defs(cls, desttype):
"""return a dictionary mapping property name to its definition for each """return a dictionary mapping property name to its definition for each
......
...@@ -9,6 +9,7 @@ class Affaire(EntityType): ...@@ -9,6 +9,7 @@ class Affaire(EntityType):
nom = String( nom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=1) order=1)
...@@ -35,6 +36,7 @@ class PersonAttrMod(EntityType): ...@@ -35,6 +36,7 @@ class PersonAttrMod(EntityType):
nom = String( nom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=1) order=1)
...@@ -42,6 +44,7 @@ class PersonAttrMod(EntityType): ...@@ -42,6 +44,7 @@ class PersonAttrMod(EntityType):
prenom = Float( prenom = Float(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=2) order=2)
...@@ -59,6 +62,7 @@ class PersonBase(EntityType): ...@@ -59,6 +62,7 @@ class PersonBase(EntityType):
nom = String( nom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=1) order=1)
...@@ -66,6 +70,7 @@ class PersonBase(EntityType): ...@@ -66,6 +70,7 @@ class PersonBase(EntityType):
prenom = String( prenom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=2) order=2)
......
...@@ -9,6 +9,7 @@ class Affaire(EntityType): ...@@ -9,6 +9,7 @@ class Affaire(EntityType):
nom = String( nom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
maxsize=150, maxsize=150,
...@@ -17,6 +18,7 @@ class Affaire(EntityType): ...@@ -17,6 +18,7 @@ class Affaire(EntityType):
numero = Int( numero = Int(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=2) order=2)
...@@ -52,6 +54,7 @@ class PersonBase(EntityType): ...@@ -52,6 +54,7 @@ class PersonBase(EntityType):
nom = String( nom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=1) order=1)
...@@ -59,6 +62,7 @@ class PersonBase(EntityType): ...@@ -59,6 +62,7 @@ class PersonBase(EntityType):
prenom = String( prenom = String(
__permissions__= { __permissions__= {
'read': ('managers','users','guests'), 'read': ('managers','users','guests'),
'add': ('managers','users'),
'update': ('managers','owners') 'update': ('managers','owners')
}, },
order=2) order=2)
......
...@@ -95,7 +95,7 @@ class PropertiesFromTC(TestCase): ...@@ -95,7 +95,7 @@ class PropertiesFromTC(TestCase):
'description': 'something'} 'description': 'something'}
self.assertEqual({'default': 'toto', self.assertEqual({'default': 'toto',
'required': True, 'required': True,
'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'update': ('managers','owners')\n\t\t}", '__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'add': ('managers','users'),\n\t\t\t'update': ('managers','owners')\n\t\t}",
'description': "'something'", 'description': "'something'",
'order': 1}, 'order': 1},
properties_from(self.build_rdef(props_ref)), properties_from(self.build_rdef(props_ref)),
...@@ -103,26 +103,26 @@ class PropertiesFromTC(TestCase): ...@@ -103,26 +103,26 @@ class PropertiesFromTC(TestCase):
def test_properties_from_final_attributes_2(self): def test_properties_from_final_attributes_2(self):
props_ref = {} props_ref = {}
self.assertEqual({'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'update': ('managers','owners')\n\t\t}", self.assertEqual({'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'add': ('managers','users'),\n\t\t\t'update': ('managers','owners')\n\t\t}",
'order': 1}, 'order': 1},
properties_from(self.build_rdef(props_ref))) properties_from(self.build_rdef(props_ref)))
def test_properties_from_final_attributes_3(self): def test_properties_from_final_attributes_3(self):
props_ref = {'default': None, 'required': False} props_ref = {'default': None, 'required': False}
self.assertEqual({'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'update': ('managers','owners')\n\t\t}", self.assertEqual({'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'add': ('managers','users'),\n\t\t\t'update': ('managers','owners')\n\t\t}",
'order': 1}, 'order': 1},
properties_from(self.build_rdef(props_ref))) properties_from(self.build_rdef(props_ref)))
def test_constraint_properties_1(self): def test_constraint_properties_1(self):
props_ref = {'maxsize': 150, 'required': False} props_ref = {'maxsize': 150, 'required': False}
self.assertEqual({'maxsize': 150, self.assertEqual({'maxsize': 150,
'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'update': ('managers','owners')\n\t\t}", '__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'add': ('managers','users'),\n\t\t\t'update': ('managers','owners')\n\t\t}",
'order': 1}, 'order': 1},
properties_from(self.build_rdef(props_ref))) properties_from(self.build_rdef(props_ref)))
def test_constraint_properties_2(self): def test_constraint_properties_2(self):
props_ref = {'unique': True, 'required': False} props_ref = {'unique': True, 'required': False}
self.assertEqual({'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'update': ('managers','owners')\n\t\t}", self.assertEqual({'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'add': ('managers','users'),\n\t\t\t'update': ('managers','owners')\n\t\t}",
'unique': True, 'unique': True,
'order': 1}, 'order': 1},
properties_from(self.build_rdef(props_ref))) properties_from(self.build_rdef(props_ref)))
...@@ -132,7 +132,7 @@ class PropertiesFromTC(TestCase): ...@@ -132,7 +132,7 @@ class PropertiesFromTC(TestCase):
rdef = self.build_rdef(props_ref) rdef = self.build_rdef(props_ref)
props_ref['maxsize'] = 5 props_ref['maxsize'] = 5
self.assertEqual({'maxsize': 5, self.assertEqual({'maxsize': 5,
'__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'update': ('managers','owners')\n\t\t}", '__permissions__': " {\n\t\t\t'read': ('managers','users','guests'),\n\t\t\t'add': ('managers','users'),\n\t\t\t'update': ('managers','owners')\n\t\t}",
'order': 1, 'order': 1,
'vocabulary': [u'aaa', u'bbbb', u'ccccc']}, 'vocabulary': [u'aaa', u'bbbb', u'ccccc']},
properties_from(rdef)) properties_from(rdef))
......
...@@ -256,6 +256,7 @@ class SchemaLoaderTC(TestCase): ...@@ -256,6 +256,7 @@ class SchemaLoaderTC(TestCase):
rschema = schema.rschema('tel') rschema = schema.rschema('tel')
self.assertEqual(rschema.rdef('Person', 'Int').permissions, self.assertEqual(rschema.rdef('Person', 'Int').permissions,
{'read': (), {'read': (),
'add': ('managers',),
'update': ('managers',)}) 'update': ('managers',)})
......
...@@ -120,7 +120,9 @@ class SpecializationTC(TestCase): ...@@ -120,7 +120,9 @@ class SpecializationTC(TestCase):
self.assertIn('custom_attr', self.schema['Student'].subjrels) self.assertIn('custom_attr', self.schema['Student'].subjrels)
self.assertEqual( self.assertEqual(
self.schema['custom_attr'].rdefs[('Student', 'String')].permissions, self.schema['custom_attr'].rdefs[('Student', 'String')].permissions,
{'read': ('managers', ), 'update': ('managers', )}) {'read': ('managers',),
'add': ('managers',),
'update': ('managers',)})
def test_remove_infered_relations(self): def test_remove_infered_relations(self):
self.schema.remove_infered_definitions() self.schema.remove_infered_definitions()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment