# HG changeset patch # User Sylvain Thénault # Date 1267688931 -3600 # Node ID e0f2ca89123f00a2d007344183af805c991b721c # Parent dd6ae651291690e55cdf1e394fab09010486b053# Parent c33d128656415e042df9ac79ef9a6d760cfbc4e9 merge diff -r dd6ae6512916 -r e0f2ca89123f devtools/__init__.py --- a/devtools/__init__.py Wed Mar 03 14:06:05 2010 +0100 +++ b/devtools/__init__.py Thu Mar 04 08:48:51 2010 +0100 @@ -30,8 +30,8 @@ SYSTEM_RELATIONS = schema.META_RTYPES | set(( # workflow related - 'workflow_of', 'state_of', 'transition_of', 'initial_state', 'allowed_transition', - 'destination_state', 'from_state', 'to_state', + 'workflow_of', 'state_of', 'transition_of', 'initial_state', 'default_workflow', + 'allowed_transition', 'destination_state', 'from_state', 'to_state', 'condition', 'subworkflow', 'subworkflow_state', 'subworkflow_exit', 'custom_workflow', 'in_state', 'wf_info_for', # cwproperty diff -r dd6ae6512916 -r e0f2ca89123f entity.py --- a/entity.py Wed Mar 03 14:06:05 2010 +0100 +++ b/entity.py Thu Mar 04 08:48:51 2010 +0100 @@ -797,7 +797,7 @@ del self.__unique except AttributeError: pass - + # raw edition utilities ################################################### def set_attributes(self, _cw_unsafe=False, **kwargs): diff -r dd6ae6512916 -r e0f2ca89123f schema.py --- a/schema.py Wed Mar 03 14:06:05 2010 +0100 +++ b/schema.py Thu Mar 04 08:48:51 2010 +0100 @@ -50,8 +50,9 @@ )) WORKFLOW_TYPES = set(('Transition', 'State', 'TrInfo', 'Workflow', - 'WorkflowTransition', 'BaseTransition', - 'SubWorkflowExitPoint')) + 'WorkflowTransition', 'BaseTransition', + 'SubWorkflowExitPoint')) + INTERNAL_TYPES = set(('CWProperty', 'CWPermission', 'CWCache', 'ExternalUri')) @@ -63,6 +64,31 @@ ybo.RDEF_PROPERTIES += ('eid',) +PUB_SYSTEM_ENTITY_PERMS = { + 'read': ('managers', 'users', 'guests',), + 'add': ('managers',), + 'delete': ('managers',), + 'update': ('managers',), + } +PUB_SYSTEM_REL_PERMS = { + 'read': ('managers', 'users', 'guests',), + 'add': ('managers',), + 'delete': ('managers',), + } +PUB_SYSTEM_ATTR_PERMS = { + 'read': ('managers', 'users', 'guests',), + 'update': ('managers',), + } +RO_REL_PERMS = { + 'read': ('managers', 'users', 'guests',), + 'add': (), + 'delete': (), + } +RO_ATTR_PERMS = { + 'read': ('managers', 'users', 'guests',), + 'update': (), + } + # XXX same algorithm as in reorder_cubes and probably other place, # may probably extract a generic function def order_eschemas(eschemas): @@ -369,7 +395,8 @@ if need_has_text is None: need_has_text = may_need_has_text if need_has_text and not has_has_text and not deletion: - rdef = ybo.RelationDefinition(self.type, 'has_text', 'String') + rdef = ybo.RelationDefinition(self.type, 'has_text', 'String', + __permissions__=RO_ATTR_PERMS) self.schema.add_relation_def(rdef) elif not need_has_text and has_has_text: self.schema.del_relation_def(self.type, 'has_text', 'String') @@ -491,9 +518,11 @@ if not eschema.final: # automatically add the eid relation to non final entity types rdef = ybo.RelationDefinition(eschema.type, 'eid', 'Int', - cardinality='11', uid=True) + cardinality='11', uid=True, + __permissions__=RO_ATTR_PERMS) self.add_relation_def(rdef) - rdef = ybo.RelationDefinition(eschema.type, 'identity', eschema.type) + rdef = ybo.RelationDefinition(eschema.type, 'identity', eschema.type, + __permissions__=RO_REL_PERMS) self.add_relation_def(rdef) self._eid_index[eschema.eid] = eschema return eschema @@ -1054,8 +1083,16 @@ cw = entity._cw elif form is not None: cw = form._cw - if cw is not None and cw.user.has_permission(PERM_USE_TEMPLATE_FORMAT): - return self.regular_formats + tuple(NEED_PERM_FORMATS) + if cw is not None: + if hasattr(cw, 'is_super_session'): + # cw is a server session + hasperm = cw.is_super_session or \ + not cw.vreg.config.is_hook_category_activated('integrity') or \ + cw.user.has_permission(PERM_USE_TEMPLATE_FORMAT) + else: + hasperm = cw.user.has_permission(PERM_USE_TEMPLATE_FORMAT) + if hasperm: + return self.regular_formats + tuple(NEED_PERM_FORMATS) return self.regular_formats # XXX monkey patch PyFileReader.import_erschema until bw_normalize_etype is diff -r dd6ae6512916 -r e0f2ca89123f schemas/__init__.py --- a/schemas/__init__.py Wed Mar 03 14:06:05 2010 +0100 +++ b/schemas/__init__.py Thu Mar 04 08:48:51 2010 +0100 @@ -1,38 +1,25 @@ """some utilities to define schema permissions :organization: Logilab -:copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +:copyright: 2008-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr """ __docformat__ = "restructuredtext en" from rql.utils import quote -from cubicweb.schema import ERQLExpression, RRQLExpression +from cubicweb.schema import RO_REL_PERMS, RO_ATTR_PERMS, \ + PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, \ + ERQLExpression, RRQLExpression # permissions for "meta" entity type (readable by anyone, can only be # added/deleted by managers) -META_ETYPE_PERMS = { - 'read': ('managers', 'users', 'guests',), - 'add': ('managers',), - 'delete': ('managers',), - 'update': ('managers', 'owners',), - } - +META_ETYPE_PERMS = PUB_SYSTEM_ENTITY_PERMS # XXX deprecates # permissions for "meta" relation type (readable by anyone, can only be # added/deleted by managers) -META_RTYPE_PERMS = { - 'read': ('managers', 'users', 'guests',), - 'add': ('managers',), - 'delete': ('managers',), - } - +META_RTYPE_PERMS = PUB_SYSTEM_REL_PERMS # XXX deprecates # permissions for relation type that should only set by hooks using unsafe # execute, readable by anyone -HOOKS_RTYPE_PERMS = { - 'read': ('managers', 'users', 'guests',), - 'add': (), - 'delete': (), - } +HOOKS_RTYPE_PERMS = RO_REL_PERMS # XXX deprecates def _perm(names): if isinstance(names, (list, tuple)): diff -r dd6ae6512916 -r e0f2ca89123f schemas/base.py --- a/schemas/base.py Wed Mar 03 14:06:05 2010 +0100 +++ b/schemas/base.py Thu Mar 04 08:48:51 2010 +0100 @@ -10,9 +10,9 @@ from yams.buildobjs import (EntityType, RelationType, SubjectRelation, String, Datetime, Password) -from cubicweb.schema import (RQLConstraint, WorkflowableEntityType, - ERQLExpression, RRQLExpression) -from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS +from cubicweb.schema import ( + RQLConstraint, WorkflowableEntityType, ERQLExpression, RRQLExpression, + PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, PUB_SYSTEM_ATTR_PERMS) class CWUser(WorkflowableEntityType): """define a CubicWeb user""" @@ -85,7 +85,7 @@ class in_group(RelationType): """core relation indicating a user's groups""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS class owned_by(RelationType): """core relation indicating owners of an entity. This relation @@ -118,18 +118,21 @@ class creation_date(RelationType): """creation time of an entity""" + __permissions__ = PUB_SYSTEM_ATTR_PERMS cardinality = '11' subject = '*' object = 'Datetime' class modification_date(RelationType): """latest modification time of an entity""" + __permissions__ = PUB_SYSTEM_ATTR_PERMS cardinality = '11' subject = '*' object = 'Datetime' class cwuri(RelationType): """internal entity uri""" + __permissions__ = PUB_SYSTEM_ATTR_PERMS cardinality = '11' subject = '*' object = 'String' @@ -155,7 +158,7 @@ class CWPermission(EntityType): """entity type that may be used to construct some advanced security configuration """ - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS name = String(required=True, indexed=True, internationalizable=True, maxsize=100, description=_('name or identifier of the permission')) @@ -170,11 +173,11 @@ """link a permission to the entity. This permission should be used in the security definition of the entity's type to be useful. """ - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS class require_group(RelationType): """used to grant a permission to a group""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS class ExternalUri(EntityType): @@ -209,6 +212,8 @@ Also, checkout the AppObject.get_cache() method. """ + # XXX only handle by hooks, shouldn't be readable/editable at all through + # the ui and so no permissions should be granted, no? __permissions__ = { 'read': ('managers', 'users', 'guests'), 'add': ('managers',), diff -r dd6ae6512916 -r e0f2ca89123f schemas/bootstrap.py --- a/schemas/bootstrap.py Wed Mar 03 14:06:05 2010 +0100 +++ b/schemas/bootstrap.py Thu Mar 04 08:48:51 2010 +0100 @@ -10,14 +10,16 @@ from yams.buildobjs import (EntityType, RelationType, RelationDefinition, SubjectRelation, RichString, String, Boolean, Int) -from cubicweb.schema import RQLConstraint -from cubicweb.schemas import META_ETYPE_PERMS, META_RTYPE_PERMS +from cubicweb.schema import ( + RQLConstraint, + PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, PUB_SYSTEM_ATTR_PERMS + ) # not restricted since as "is" is handled as other relations, guests need # access to this class CWEType(EntityType): """define an entity type, used to build the instance schema""" - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS name = String(required=True, indexed=True, internationalizable=True, unique=True, maxsize=64) description = RichString(internationalizable=True, @@ -28,7 +30,7 @@ class CWRType(EntityType): """define a relation type, used to build the instance schema""" - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS name = String(required=True, indexed=True, internationalizable=True, unique=True, maxsize=64) description = RichString(internationalizable=True, @@ -48,7 +50,7 @@ used to build the instance schema """ - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS relation_type = SubjectRelation('CWRType', cardinality='1*', constraints=[RQLConstraint('O final TRUE')], composite='object') @@ -85,7 +87,7 @@ used to build the instance schema """ - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS relation_type = SubjectRelation('CWRType', cardinality='1*', constraints=[RQLConstraint('O final FALSE')], composite='object') @@ -116,7 +118,7 @@ # not restricted since it has to be read when checking allowed transitions class RQLExpression(EntityType): """define a rql expression used to define permissions""" - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS exprtype = String(required=True, vocabulary=['ERQLExpression', 'RRQLExpression']) mainvars = String(maxsize=8, description=_('name of the main variables which should be ' @@ -134,14 +136,14 @@ class CWConstraint(EntityType): """define a schema constraint""" - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS cstrtype = SubjectRelation('CWConstraintType', cardinality='1*') value = String(description=_('depends on the constraint type')) class CWConstraintType(EntityType): """define a schema constraint type""" - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS name = String(required=True, indexed=True, internationalizable=True, unique=True, maxsize=64) @@ -149,7 +151,7 @@ # not restricted since it has to be read when checking allowed transitions class CWGroup(EntityType): """define a CubicWeb users group""" - __permissions__ = META_ETYPE_PERMS + __permissions__ = PUB_SYSTEM_ENTITY_PERMS name = String(required=True, indexed=True, internationalizable=True, unique=True, maxsize=64) @@ -173,32 +175,32 @@ class relation_type(RelationType): """link a relation definition to its relation type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS inlined = True class from_entity(RelationType): """link a relation definition to its subject entity type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS inlined = True class to_entity(RelationType): """link a relation definition to its object entity type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS inlined = True class constrained_by(RelationType): """constraints applying on this relation""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS class cstrtype(RelationType): """constraint factory""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS inlined = True class read_permission_cwgroup(RelationDefinition): """groups allowed to read entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'read_permission' subject = ('CWEType', 'CWAttribute', 'CWRelation') object = 'CWGroup' @@ -206,7 +208,7 @@ class add_permission_cwgroup(RelationDefinition): """groups allowed to add entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'add_permission' subject = ('CWEType', 'CWRelation') object = 'CWGroup' @@ -214,7 +216,7 @@ class delete_permission_cwgroup(RelationDefinition): """groups allowed to delete entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'delete_permission' subject = ('CWEType', 'CWRelation') object = 'CWGroup' @@ -222,7 +224,7 @@ class update_permission_cwgroup(RelationDefinition): """groups allowed to update entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'update_permission' subject = ('CWEType', 'CWAttribute') object = 'CWGroup' @@ -230,7 +232,7 @@ class read_permission_rqlexpr(RelationDefinition): """rql expression allowing to read entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'read_permission' subject = ('CWEType', 'CWAttribute', 'CWRelation') object = 'RQLExpression' @@ -239,7 +241,7 @@ class add_permission_rqlexpr(RelationDefinition): """rql expression allowing to add entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'add_permission' subject = ('CWEType', 'CWRelation') object = 'RQLExpression' @@ -248,7 +250,7 @@ class delete_permission_rqlexpr(RelationDefinition): """rql expression allowing to delete entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'delete_permission' subject = ('CWEType', 'CWRelation') object = 'RQLExpression' @@ -257,7 +259,7 @@ class update_permission_rqlexpr(RelationDefinition): """rql expression allowing to update entities/relations of this type""" - __permissions__ = META_RTYPE_PERMS + __permissions__ = PUB_SYSTEM_REL_PERMS name = 'update_permission' subject = ('CWEType', 'CWAttribute') object = 'RQLExpression' @@ -305,3 +307,13 @@ cardinality = '?*' subject = 'CWEType' object = 'CWEType' + +def post_build_callback(schema): + """set attributes permissions for schema/workflow entities""" + from cubicweb.schema import SCHEMA_TYPES, WORKFLOW_TYPES, META_RTYPES + for eschema in schema.entities(): + if eschema in SCHEMA_TYPES or eschema in WORKFLOW_TYPES: + for rschema in eschema.subject_relations(): + if rschema.final and not rschema in META_RTYPES: + rdef = eschema.rdef(rschema) + rdef.permissions = PUB_SYSTEM_ATTR_PERMS diff -r dd6ae6512916 -r e0f2ca89123f server/__init__.py --- a/server/__init__.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/__init__.py Thu Mar 04 08:48:51 2010 +0100 @@ -186,6 +186,7 @@ handler.install_custom_sql_scripts(join(CW_SOFTWARE_ROOT, 'schemas'), driver) for directory in reversed(config.cubes_path()): handler.install_custom_sql_scripts(join(directory, 'schema'), driver) + # serialize the schema initialize_schema(config, schema, handler) # yoo ! cnx.commit() diff -r dd6ae6512916 -r e0f2ca89123f server/querier.py --- a/server/querier.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/querier.py Thu Mar 04 08:48:51 2010 +0100 @@ -358,6 +358,7 @@ self.preprocess(rqlst, security=False) return rqlst + class InsertPlan(ExecutionPlan): """an execution model specific to the INSERT rql query """ diff -r dd6ae6512916 -r e0f2ca89123f server/repository.py --- a/server/repository.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/repository.py Thu Mar 04 08:48:51 2010 +0100 @@ -105,7 +105,8 @@ # skip that for super session (though we can still skip it for internal # sessions). Also we should imo rely on the orm to first fetch existing # entity if any then delete it. - if session.is_internal_session: + if session.is_internal_session \ + or not session.vreg.config.is_hook_category_activated('integrity'): return card = session.schema_rproperty(rtype, eidfrom, eidto, 'cardinality') # one may be tented to check for neweids but this may cause more than one diff -r dd6ae6512916 -r e0f2ca89123f server/schemaserial.py --- a/server/schemaserial.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/schemaserial.py Thu Mar 04 08:48:51 2010 +0100 @@ -51,10 +51,6 @@ return res # schema / perms deserialization ############################################## -OLD_SCHEMA_TYPES = frozenset(('EFRDef', 'ENFRDef', 'ERType', 'EEType', - 'EConstraintType', 'EConstraint', 'EGroup', - 'EUser', 'ECache', 'EPermission', 'EProperty')) - def deserialize_schema(schema, session): """return a schema according to information stored in an rql database as CWRType and CWEType entities @@ -90,12 +86,6 @@ {'x': eid, 'n': netype}) session.system_sql('UPDATE entities SET type=%(n)s WHERE type=%(x)s', {'x': etype, 'n': netype}) - # XXX should be donne as well on sqlite based sources - if not etype in OLD_SCHEMA_TYPES and \ - (getattr(dbhelper, 'case_sensitive', False) - or etype.lower() != netype.lower()): - session.system_sql('ALTER TABLE %s%s RENAME TO %s%s' % ( - sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype)) session.commit(False) try: session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s', @@ -182,6 +172,17 @@ res.setdefault(eid, {}).setdefault(action, []).append( (expr, mainvars, expreid) ) return res +def deserialize_rdef_constraints(session): + """return the list of relation definition's constraints as instances""" + res = {} + for rdefeid, ceid, ct, val in session.execute( + 'Any E, X,TN,V WHERE E constrained_by X, X is CWConstraint, ' + 'X cstrtype T, T name TN, X value V', build_descr=False): + cstr = CONSTRAINTS[ct].deserialize(val) + cstr.eid = ceid + res.setdefault(rdefeid, []).append(cstr) + return res + def set_perms(erschema, permsdict): """set permissions on the given erschema according to the permission definition dictionary as built by deserialize_ertype_permissions for a @@ -202,21 +203,9 @@ for p in somethings) -def deserialize_rdef_constraints(session): - """return the list of relation definition's constraints as instances""" - res = {} - for rdefeid, ceid, ct, val in session.execute( - 'Any E, X,TN,V WHERE E constrained_by X, X is CWConstraint, ' - 'X cstrtype T, T name TN, X value V', build_descr=False): - cstr = CONSTRAINTS[ct].deserialize(val) - cstr.eid = ceid - res.setdefault(rdefeid, []).append(cstr) - return res - - # schema / perms serialization ################################################ -def serialize_schema(cursor, schema, verbose=False): +def serialize_schema(cursor, schema): """synchronize schema and permissions in the database according to current schema """ @@ -224,38 +213,40 @@ if not quiet: _title = '-> storing the schema in the database ' print _title, - execute = cursor.execute + execute = cursor.unsafe_execute eschemas = schema.entities() aller = eschemas + schema.relations() - if not verbose and not quiet: + if not quiet: pb_size = len(aller) + len(CONSTRAINTS) + len([x for x in eschemas if x.specializes()]) pb = ProgressBar(pb_size, title=_title) else: pb = None + # serialize all entity types, assuring CWEType is serialized first + eschemas.remove(schema.eschema('CWEType')) + eschemas.insert(0, schema.eschema('CWEType')) + for eschema in eschemas: + execschemarql(execute, eschema, eschema2rql(eschema, groupmap)) + if pb is not None: + pb.update() + # serialize constraint types rql = 'INSERT CWConstraintType X: X name %(ct)s' for cstrtype in CONSTRAINTS: - if verbose: - print rql execute(rql, {'ct': unicode(cstrtype)}, build_descr=False) if pb is not None: pb.update() - groupmap = group_mapping(cursor, interactive=False) - for ertype in aller: - # skip eid and has_text relations - if ertype in VIRTUAL_RTYPES: + # serialize relations + for rschema in schema.relations(): + # skip virtual relations such as eid, has_text and identity + if rschema in VIRTUAL_RTYPES: if pb is not None: pb.update() continue for rql, kwargs in erschema2rql(schema[ertype], groupmap): - if verbose: - print rql % kwargs execute(rql, kwargs, build_descr=False) if pb is not None: pb.update() for rql, kwargs in specialize2rql(schema): - if verbose: - print rql % kwargs - execute(rql, kwargs, build_descr=False) + assert execute(rql, kwargs, build_descr=False) if pb is not None: pb.update() if not quiet: diff -r dd6ae6512916 -r e0f2ca89123f server/serverconfig.py --- a/server/serverconfig.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/serverconfig.py Thu Mar 04 08:48:51 2010 +0100 @@ -185,6 +185,8 @@ # check user's state at login time consider_user_state = True + # XXX hooks control stuff should probably be on the session, not on the config + # hooks activation configuration # all hooks should be activated during normal execution disabled_hooks_categories = set() @@ -232,9 +234,13 @@ @classmethod def is_hook_activated(cls, hook): + return cls.is_hook_category_activated(hook.category) + + @classmethod + def is_hook_category_activated(cls, category): if cls.hooks_mode is cls.DENY_ALL: - return hook.category in cls.enabled_hooks_categories - return hook.category not in cls.disabled_hooks_categories + return category in cls.enabled_hooks_categories + return category not in cls.disabled_hooks_categories # should some hooks be deactivated during [pre|post]create script execution free_wheel = False diff -r dd6ae6512916 -r e0f2ca89123f server/session.py --- a/server/session.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/session.py Thu Mar 04 08:48:51 2010 +0100 @@ -499,7 +499,7 @@ operation.handle_event('revert%s_event' % trstate) # XXX use slice notation since self.pending_operations is a # read-only property. - self.pending_operations[:] = processed + self.pending_operations + self.pending_operations[:] = processed + self.pending_operations self.rollback(reset_pool) raise self.pool.commit() diff -r dd6ae6512916 -r e0f2ca89123f server/test/unittest_querier.py --- a/server/test/unittest_querier.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/test/unittest_querier.py Thu Mar 04 08:48:51 2010 +0100 @@ -257,7 +257,7 @@ result, descr = rset.rows, rset.description self.assertEquals(descr[0][0], 'String') self.assertEquals(descr[0][1], 'Int') - self.assertEquals(result[0][0], 'RQLExpression') # XXX may change as schema evolve + self.assertEquals(result[0][0], 'CWRelation') # XXX may change as schema evolve def test_select_groupby_orderby(self): rset = self.execute('Any N GROUPBY N ORDERBY N WHERE X is CWGroup, X name N') @@ -862,6 +862,14 @@ self.assert_(rset.rows) self.assertEquals(rset.description, [('Personne', 'Societe',)]) + def test_insert_5bis(self): + peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0] + self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s", + {'x': peid}, 'x') + rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y') + self.assert_(rset.rows) + self.assertEquals(rset.description, [('Personne', 'Societe',)]) + def test_insert_6(self): self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto', X travaille Y") rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y') diff -r dd6ae6512916 -r e0f2ca89123f server/test/unittest_security.py --- a/server/test/unittest_security.py Wed Mar 03 14:06:05 2010 +0100 +++ b/server/test/unittest_security.py Thu Mar 04 08:48:51 2010 +0100 @@ -257,6 +257,26 @@ self.assertEquals(rset.rows, [[aff2]]) rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': aff2}, 'x') self.assertEquals(rset.rows, []) + # test can't update an attribute of an entity that can't be readen + self.assertRaises(Unauthorized, cu.execute, 'SET X sujet "hacked" WHERE X eid %(x)s', {'x': eid}, 'x') + + + def test_entity_created_in_transaction(self): + affschema = self.schema['Affaire'] + origperms = affschema.permissions['read'] + affschema.set_action_permissions('read', affschema.permissions['add']) + try: + cnx = self.login('iaminusersgrouponly') + cu = cnx.cursor() + aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0] + # entity created in transaction are readable *by eid* + self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}, 'x')) + # XXX would be nice if it worked + rset = cu.execute("Affaire X WHERE X sujet 'cool'") + self.assertEquals(len(rset), 0) + finally: + affschema.set_action_permissions('read', origperms) + cnx.close() def test_read_erqlexpr_has_text1(self): aff1 = self.execute("INSERT Affaire X: X sujet 'cool'")[0][0] diff -r dd6ae6512916 -r e0f2ca89123f web/test/unittest_views_editforms.py --- a/web/test/unittest_views_editforms.py Wed Mar 03 14:06:05 2010 +0100 +++ b/web/test/unittest_views_editforms.py Thu Mar 04 08:48:51 2010 +0100 @@ -43,13 +43,11 @@ ('firstname', 'subject'), ('surname', 'subject'), ('in_group', 'subject'), - ('eid', 'subject'), ]) self.assertListEquals(rbc(e, 'muledit', 'attributes'), [('login', 'subject'), ('upassword', 'subject'), ('in_group', 'subject'), - ('eid', 'subject'), ]) self.assertListEquals(rbc(e, 'main', 'metadata'), [('last_login_time', 'subject'), @@ -76,13 +74,10 @@ # owned_by is defined both as subject and object relations on CWUser self.assertListEquals(sorted(x for x in rbc(e, 'main', 'hidden') if x != ('tags', 'object')), - sorted([('has_text', 'subject'), - ('identity', 'subject'), - ('for_user', 'object'), + sorted([('for_user', 'object'), ('created_by', 'object'), ('wf_info_for', 'object'), ('owned_by', 'object'), - ('identity', 'object'), ])) def test_inlined_view(self): @@ -106,11 +101,9 @@ ('test', 'subject'), ('description', 'subject'), ('salary', 'subject'), - ('eid', 'subject') ]) self.assertListEquals(rbc(e, 'muledit', 'attributes'), [('nom', 'subject'), - ('eid', 'subject') ]) self.assertListEquals(rbc(e, 'main', 'metadata'), [('creation_date', 'subject'), @@ -124,10 +117,7 @@ ('connait', 'object') ]) self.assertListEquals(rbc(e, 'main', 'hidden'), - [('has_text', 'subject'), - ('identity', 'subject'), - ('identity', 'object'), - ]) + []) def test_edition_form(self): rset = self.execute('CWUser X LIMIT 1') diff -r dd6ae6512916 -r e0f2ca89123f web/views/autoform.py --- a/web/views/autoform.py Wed Mar 03 14:06:05 2010 +0100 +++ b/web/views/autoform.py Thu Mar 04 08:48:51 2010 +0100 @@ -661,7 +661,7 @@ return [] # XXX we should simply put eid in the generated section, no? return [(rtype, role) for rtype, _, role in self._relations_by_section( - 'attributes', 'update', strict) if rtype != 'eid'] + 'attributes', 'update', strict)] def editable_relations(self): """return a sorted list of (relation's label, relation'schema, role) for