Nice... thank you, Niphlod... I hadn't even considered checking that field 
attribute directly like that. 

Henry

On Wednesday, April 16, 2014 1:14:21 PM UTC-7, Niphlod wrote:
>
> it's not that far-fetch to include a control for writable = False 
> fields.....
>
> def PUT(table_name, record_id, **vars):
>     tb = db[table_name]
>     cant_update_those = [tb[k] for k in tb.fields if tb[k].writable is 
> False]
>     invalid_fields = set(vars) && set(cant_update_those)
>     if invalid_fields:
>         raise HTTP(400, 'whatever')
>     return db(tb._id==record_id).validate_and_update(**vars)
>
> ask for more details if needed.
>
> On Wednesday, April 16, 2014 8:15:42 PM UTC+2, Henry Nguyen wrote:
>>
>> Simply inserting into the tables blindly was the problem, as Massimo 
>> pointed out. I've gone ahead and implemented manual checking of the vars:
>>
>>     def PUT(*args, **vars):
>>
>>         required_vars = ['id']
>>         optional_vars = ['first_name','last_name']
>>         
>>         # Check for required vars
>>         for var in required_vars:
>>             if var not in vars.keys():
>>                 raise HTTP(400, 'Missing:  ' + var)
>>
>>         # Check that vars are only allowed vars
>>         for key in vars.keys():
>>             if key not in required_vars and key not in optional_vars:
>>                 raise HTTP(400, 'Invalid: ' + key)
>>
>>         result = db(
>>             (db.person.id == vars.get('id')) &
>>             (db.person.auth_user_id == auth.user.id)
>>         ).validate_and_update(**vars)
>>
>>         return dict(result=result)
>>
>> I was hoping there'd be an easier way to specify validation constraints 
>> for the REST calls, similar to db.table.field.writable = False. 
>> Unfortunately, this only applies to the built-in SQLFORMs.
>>
>> Henry
>>
>> On Wednesday, April 16, 2014 11:06:42 AM UTC-7, Derek wrote:
>>>
>>> You're right, I guess you should store the ID in session state... but 
>>> wait, this is ReST... part of the url then, and not a parameter. and PUT 
>>> should not take the record_id.
>>>
>>> On Saturday, April 12, 2014 3:01:20 PM UTC-7, Massimo Di Pierro wrote:
>>>>
>>>> That is not a hole.
>>>>
>>>> This code:
>>>>
>>>>
>>>> def PUT(table_name, record_id, **vars):
>>>>         return db(db[table_name]._id==record_id).validate_and_update(**
>>>> vars)
>>>>
>>>> means:
>>>>
>>>> "allow anybody to put any content in any record of any table". If that 
>>>> is not what you want you should write different code.
>>>>
>>>> On Friday, 11 April 2014 12:36:43 UTC-5, Derek wrote:
>>>>>
>>>>> That seems like a pretty big hole then especially if IDs are used as 
>>>>> foreign keys... ownership doesn't mean anything. I could write an 
>>>>> inflammatory comment on a website, change the owner to someone else (via 
>>>>> the edit form) and then suddenly that other user is banned...
>>>>>
>>>>> On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:
>>>>>>
>>>>>> > Does "db.person.id.writable = False" only apply to SQLFORMs?
>>>>>>
>>>>>> yes. 
>>>>>>
>>>>>> On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:
>>>>>>>
>>>>>>> Our product is using the @request.restful() decorator to specify 
>>>>>>> REST endpoints for our resources. During testing, I noticed that I can 
>>>>>>> specify a PUT request var of "id=x" where x is some new id and the id 
>>>>>>> of 
>>>>>>> that row will change to x. This is even WITH "db.table.id.writable = 
>>>>>>> False." 
>>>>>>>
>>>>>>> The PUT method is defined as follows:
>>>>>>>
>>>>>>> def PUT(table_name, record_id, **vars):
>>>>>>>         return db(db[table_name]._id==record_id).validate_and_update
>>>>>>> (**vars)
>>>>>>>
>>>>>>> So, for example, on a db with "db.person.id.writable = False", a 
>>>>>>> request to "
>>>>>>> http://127.0.0.1:8000/appname/default/api/person/1?id=100"; will 
>>>>>>> modify the person row with id 1 to be id 100.
>>>>>>>
>>>>>>> This seems like a relatively major problem... if a user were to be 
>>>>>>> clever enough to play around with our UI and figure out the REST calls 
>>>>>>> being made, he/she could potentially mess with all the ids and 
>>>>>>> relationships of the resources, at least for that particular account 
>>>>>>> (and 
>>>>>>> any other resources we've exposed).
>>>>>>>
>>>>>>> Am I missing something? Does "db.person.id.writable = False" only 
>>>>>>> apply to SQLFORMs? Is there some other way to prevent modification of 
>>>>>>> the 
>>>>>>> id field?
>>>>>>>
>>>>>>> Thanks ahead of time for any help.
>>>>>>>
>>>>>>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to