Commits

Anonymous committed 354e237

First step towards reimplementing parameter tampering protection

Comments (0)

Files changed (2)

tests/test_utils.py

             'id' : None,
             'nick' : 'bazaar',
             'other' : {
-                'id' : 1,
                 'name' : 'foo'
             }
         }
        
-        e = twsu.from_dict(self.DBTestCls2(), d)
+        x = self.DBTestCls2()
+        self.session.add(x)
+        e = twsu.from_dict(x, d)
         if hasattr(self, 'session'):
             self.session.flush()
         assert( e.id == 3 )
         assert( e.nick == 'bazaar' )
-        assert( e.other.id == 1 )
         assert( e.other.name == 'foo' )
 
     def test_from_dict_new_many_to_one_by_dict(self):
             }
         }
        
-        e = twsu.from_dict(self.DBTestCls2(), d)
+        x = self.DBTestCls2()
+        self.session.add(x)
+        e = twsu.from_dict(x, d)
         if hasattr(self, 'session'):
             self.session.flush()
         print e.id
             assert(str(e) == 'Cannot send mixed (dict/non dict) data ' +
                              'to list relationships in from_dict data.')
    
+    def test_from_dict_prm_tamp_mto(self):
+        # DBTestCls2 has a ManyToOne relation to DBTestCls1
+        # When updating a DBTestCls2 object, it should only be possible to modify
+        # a DBTestCls1 object that is related to that object.
+        prev_name = self.DBTestCls1.query.get(1).name
+        twsu.from_dict(self.DBTestCls2.query.get(2), {'other': {'id':1, 'name':prev_name+'_fred'}})
+        assert(self.DBTestCls1.query.get(1).name == prev_name)
+
     def test_update_or_create(self):
         d = { 'name' : 'winboat' }
         e = twsu.update_or_create(self.DBTestCls1, d)

tw2/sqla/utils.py

 
     for key, value in data.iteritems():
         if isinstance(value, dict):
-            rel_class = mapper.get_property(key).mapper.class_
-            record = update_or_create(rel_class, value)
-            setattr(entity, key, record)
+            record = getattr(entity, key)
+            if not record:
+                record = mapper.get_property(key).mapper.class_()
+                setattr(entity, key, record)
+            from_dict(record, value)
         elif isinstance(value, list) and \
              value and isinstance(value[0], dict):