fixes #16: remove unwanted keys in PUT/POST requests
This commit is contained in:
parent
f57923f0e9
commit
e4355a8ff2
1 changed files with 38 additions and 29 deletions
67
ibt2.py
67
ibt2.py
|
@ -84,7 +84,9 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||||
:type data: dict"""
|
:type data: dict"""
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
for key in data.keys():
|
for key in data.keys():
|
||||||
if isinstance(key, (str, unicode)) and key.startswith('$'):
|
if (isinstance(key, (str, unicode)) and key.startswith('$')) or key in ('_id', 'created_by',
|
||||||
|
'created_at', 'updated_by',
|
||||||
|
'updated_at'):
|
||||||
del data[key]
|
del data[key]
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -168,7 +170,15 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||||
self.write({'error': True, 'message': message})
|
self.write({'error': True, 'message': message})
|
||||||
|
|
||||||
def has_permission(self, owner_id):
|
def has_permission(self, owner_id):
|
||||||
if (owner_id and str(self.current_user_info.get('_id')) != str(owner_id) and not
|
"""Check if the given owner_id matches with the current user or the logged in user is an admin; if not,
|
||||||
|
build an error reply.
|
||||||
|
|
||||||
|
:param owner_id: owner ID to check against
|
||||||
|
:type owner_id: str, ObjectId, None
|
||||||
|
|
||||||
|
:returns: if the logged in user has the permission
|
||||||
|
:rtype: bool"""
|
||||||
|
if (owner_id and str(self.current_user) != str(owner_id) and not
|
||||||
self.current_user_info.get('isAdmin')):
|
self.current_user_info.get('isAdmin')):
|
||||||
self.build_error(status=401, message='insufficient permissions: must be the owner or admin')
|
self.build_error(status=401, message='insufficient permissions: must be the owner or admin')
|
||||||
return False
|
return False
|
||||||
|
@ -180,6 +190,23 @@ class BaseHandler(tornado.web.RequestHandler):
|
||||||
del self._users_cache[self.current_user]
|
del self._users_cache[self.current_user]
|
||||||
self.clear_cookie("user")
|
self.clear_cookie("user")
|
||||||
|
|
||||||
|
def add_access_info(self, doc):
|
||||||
|
"""Add created/updated by/at to a document (modified in place and returned).
|
||||||
|
|
||||||
|
:param doc: the doc to be updated
|
||||||
|
:type doc: dict
|
||||||
|
:returns: the updated document
|
||||||
|
:rtype: dict"""
|
||||||
|
user_id = self.current_user
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
if 'created_by' not in doc:
|
||||||
|
doc['created_by'] = user_id
|
||||||
|
if 'created_at' not in doc:
|
||||||
|
doc['created_at'] = now
|
||||||
|
doc['updated_by'] = user_id
|
||||||
|
doc['updated_at'] = now
|
||||||
|
return doc
|
||||||
|
|
||||||
|
|
||||||
class RootHandler(BaseHandler):
|
class RootHandler(BaseHandler):
|
||||||
"""Handler for the / path."""
|
"""Handler for the / path."""
|
||||||
|
@ -212,30 +239,19 @@ class AttendeesHandler(BaseHandler):
|
||||||
if not value:
|
if not value:
|
||||||
return self.build_error(status=404, message="%s can't be empty" % key)
|
return self.build_error(status=404, message="%s can't be empty" % key)
|
||||||
data[key] = value
|
data[key] = value
|
||||||
user_id = self.current_user_info.get('_id')
|
self.add_access_info(data)
|
||||||
now = datetime.datetime.now()
|
|
||||||
data['created_by'] = user_id
|
|
||||||
data['created_at'] = now
|
|
||||||
data['updated_by'] = user_id
|
|
||||||
data['updated_at'] = now
|
|
||||||
doc = self.db.add(self.collection, data)
|
doc = self.db.add(self.collection, data)
|
||||||
self.write(doc)
|
self.write(doc)
|
||||||
|
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def put(self, id_, **kwargs):
|
def put(self, id_, **kwargs):
|
||||||
data = self.clean_body
|
data = self.clean_body
|
||||||
if '_id' in data:
|
|
||||||
del data['_id']
|
|
||||||
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
||||||
if not doc:
|
if not doc:
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
owner_id = doc.get('created_by')
|
if not self.has_permission(doc.get('created_by')):
|
||||||
if not self.has_permission(owner_id):
|
|
||||||
return
|
return
|
||||||
user_id = self.current_user_info.get('_id')
|
self.add_access_info(data)
|
||||||
now = datetime.datetime.now()
|
|
||||||
data['updated_by'] = user_id
|
|
||||||
data['updated_at'] = now
|
|
||||||
merged, doc = self.db.update(self.collection, {'_id': id_}, data)
|
merged, doc = self.db.update(self.collection, {'_id': id_}, data)
|
||||||
self.write(doc)
|
self.write(doc)
|
||||||
|
|
||||||
|
@ -247,8 +263,7 @@ class AttendeesHandler(BaseHandler):
|
||||||
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
||||||
if not doc:
|
if not doc:
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
owner_id = doc.get('created_by')
|
if not self.has_permission(doc.get('created_by')):
|
||||||
if not self.has_permission(owner_id):
|
|
||||||
return
|
return
|
||||||
howMany = self.db.delete(self.collection, id_)
|
howMany = self.db.delete(self.collection, id_)
|
||||||
self.write({'success': True, 'deleted entries': howMany.get('n')})
|
self.write({'success': True, 'deleted entries': howMany.get('n')})
|
||||||
|
@ -327,13 +342,11 @@ class DaysHandler(BaseHandler):
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def put(self, **kwargs):
|
def put(self, **kwargs):
|
||||||
data = self.clean_body
|
data = self.clean_body
|
||||||
now = datetime.datetime.now()
|
|
||||||
data['updated_by'] = self.current_user_info.get('_id')
|
|
||||||
data['updated_at'] = now
|
|
||||||
day = (data.get('day') or '').strip()
|
day = (data.get('day') or '').strip()
|
||||||
if not day:
|
if not day:
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
data['day'] = day
|
data['day'] = day
|
||||||
|
self.add_access_info(data)
|
||||||
merged, doc = self.db.update('days', {'day': day}, data)
|
merged, doc = self.db.update('days', {'day': day}, data)
|
||||||
self.write(doc)
|
self.write(doc)
|
||||||
|
|
||||||
|
@ -343,15 +356,13 @@ class GroupsHandler(BaseHandler):
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def put(self, **kwargs):
|
def put(self, **kwargs):
|
||||||
data = self.clean_body
|
data = self.clean_body
|
||||||
now = datetime.datetime.now()
|
|
||||||
data['updated_by'] = self.current_user_info.get('_id')
|
|
||||||
data['updated_at'] = now
|
|
||||||
day = (data.get('day') or '').strip()
|
day = (data.get('day') or '').strip()
|
||||||
group = (data.get('group') or '').strip()
|
group = (data.get('group') or '').strip()
|
||||||
if not (day and group):
|
if not (day and group):
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
data['day'] = day
|
data['day'] = day
|
||||||
data['group'] = group
|
data['group'] = group
|
||||||
|
self.add_access_info(data)
|
||||||
merged, doc = self.db.update('groups', {'day': day, 'group': group}, data)
|
merged, doc = self.db.update('groups', {'day': day, 'group': group}, data)
|
||||||
self.write(doc)
|
self.write(doc)
|
||||||
|
|
||||||
|
@ -381,8 +392,6 @@ class UsersHandler(BaseHandler):
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def post(self, **kwargs):
|
def post(self, **kwargs):
|
||||||
data = self.clean_body
|
data = self.clean_body
|
||||||
if '_id' in data:
|
|
||||||
del data['_id']
|
|
||||||
username = (data.get('username') or '').strip()
|
username = (data.get('username') or '').strip()
|
||||||
password = (data.get('password') or '').strip()
|
password = (data.get('password') or '').strip()
|
||||||
email = (data.get('email') or '').strip()
|
email = (data.get('email') or '').strip()
|
||||||
|
@ -392,8 +401,9 @@ class UsersHandler(BaseHandler):
|
||||||
if res:
|
if res:
|
||||||
raise InputException('username already exists')
|
raise InputException('username already exists')
|
||||||
data['username'] = username
|
data['username'] = username
|
||||||
data['email'] = email
|
|
||||||
data['password'] = utils.hash_password(password)
|
data['password'] = utils.hash_password(password)
|
||||||
|
data['email'] = email
|
||||||
|
self.add_access_info(data)
|
||||||
if 'isAdmin' in data and not self.current_user_info.get('isAdmin'):
|
if 'isAdmin' in data and not self.current_user_info.get('isAdmin'):
|
||||||
del data['isAdmin']
|
del data['isAdmin']
|
||||||
doc = self.db.add(self.collection, data)
|
doc = self.db.add(self.collection, data)
|
||||||
|
@ -408,8 +418,6 @@ class UsersHandler(BaseHandler):
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
if not self.has_permission(id_):
|
if not self.has_permission(id_):
|
||||||
return
|
return
|
||||||
if '_id' in data:
|
|
||||||
del data['_id']
|
|
||||||
if 'username' in data:
|
if 'username' in data:
|
||||||
del data['username']
|
del data['username']
|
||||||
if 'isAdmin' in data and (str(self.current_user) == id_ or not self.current_user_info.get('isAdmin')):
|
if 'isAdmin' in data and (str(self.current_user) == id_ or not self.current_user_info.get('isAdmin')):
|
||||||
|
@ -420,6 +428,7 @@ class UsersHandler(BaseHandler):
|
||||||
data['password'] = utils.hash_password(password)
|
data['password'] = utils.hash_password(password)
|
||||||
else:
|
else:
|
||||||
del data['password']
|
del data['password']
|
||||||
|
self.add_access_info(data)
|
||||||
merged, doc = self.db.update(self.collection, {'_id': id_}, data)
|
merged, doc = self.db.update(self.collection, {'_id': id_}, data)
|
||||||
if 'password' in doc:
|
if 'password' in doc:
|
||||||
del doc['password']
|
del doc['password']
|
||||||
|
|
Loading…
Reference in a new issue