From 13c8cc320823d44668c1e89fd35f7f2154caebfc Mon Sep 17 00:00:00 2001 From: Davide Alberani Date: Sat, 11 Jun 2016 00:47:29 +0200 Subject: [PATCH] introduce basic data filters --- eventman_server.py | 51 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/eventman_server.py b/eventman_server.py index bdc1980..2fbe68a 100755 --- a/eventman_server.py +++ b/eventman_server.py @@ -67,8 +67,8 @@ class BaseHandler(tornado.web.RequestHandler): """Base class for request handlers.""" permissions = { 'event|read': True, - 'events-all|read': True, 'event:tickets|all': True, + 'events-all|read': True, 'person|create': True } @@ -215,10 +215,19 @@ class CollectionHandler(BaseHandler): operation='increment') return doc.get('seq', 0) - def gen_id(self, seq='ids'): + def gen_id(self, seq='ids', random_alpha=32): + """Generate a unique, non-guessable ID. + + :param seq: the scope of the ever-incrementing sequence + :type seq: str + :param random_alpha: number of random lowercase alphanumeric chars + :type random_alpha: int + + :return: unique ID + :rtype: str""" t = str(time.time()).replace('.', '_') seq = str(self.get_next_seq(seq)) - rand = ''.join([random.choice(self._id_chars) for x in xrange(32)]) + rand = ''.join([random.choice(self._id_chars) for x in xrange(random_alpha)]) return '-'.join((t, seq, rand)) def _filter_results(self, results, params): @@ -275,6 +284,12 @@ class CollectionHandler(BaseHandler): continue return ret + def apply_filter(self, output, filter_name): + filter_method = getattr(self, filter_name, None) + if filter_method is not None: + output = filter_method(output) + return output + @gen.coroutine @authenticated def get(self, id_=None, resource=None, resource_id=None, acl=True, **kwargs): @@ -285,9 +300,8 @@ class CollectionHandler(BaseHandler): return self.build_error(status=401, message='insufficient permissions: %s' % permission) method = getattr(self, 'handle_get_%s' % resource, None) if method and callable(method): - output = method(id_, resource_id, **kwargs) - if output is not None: - self.write(output) + output = method(id_, resource_id, **kwargs) or {} + self.write(output) return return self.build_error(status=404, message='unable to access resource: %s' % resource) if id_ is not None: @@ -295,7 +309,9 @@ class CollectionHandler(BaseHandler): permission = '%s|read' % self.document if acl and not self.has_permission(permission): return self.build_error(status=401, message='insufficient permissions: %s' % permission) - self.write(self.db.get(self.collection, id_)) + output = self.db.get(self.collection, id_) + output = self.apply_filter(output, 'filter_get') + self.write(output) else: # return an object containing the list of all objects in the collection; # e.g.: {'events': [{'_id': 'obj1-id, ...}, {'_id': 'obj2-id, ...}, ...]} @@ -304,7 +320,9 @@ class CollectionHandler(BaseHandler): permission = '%s-all|read' % self.collection if acl and not self.has_permission(permission): return self.build_error(status=401, message='insufficient permissions: %s' % permission) - self.write({self.collection: self.db.query(self.collection, self.arguments)}) + output = {self.collection: self.db.query(self.collection, self.arguments)} + output = self.apply_filter(output, 'filter_get_all') + self.write(output) @gen.coroutine @authenticated @@ -322,12 +340,12 @@ class CollectionHandler(BaseHandler): self.write(handler(id_, resource_id, data, **kwargs)) return if id_ is None: - permission = '%s|%s' % (self.document, 'create' if method == 'post' else 'update') + permission = '%s-all|%s' % (self.collection, 'create' if method == 'post' else 'update') if not self.has_permission(permission): return self.build_error(status=401, message='insufficient permissions: %s' % permission) newData = self.db.add(self.collection, data, _id=self.gen_id()) else: - permission = '%s|%s' % (self.collection, 'create' if method == 'post' else 'update') + permission = '%s|%s' % (self.document, 'create' if method == 'post' else 'update') if not self.has_permission(permission): return self.build_error(status=401, message='insufficient permissions: %s' % permission) merged, newData = self.db.update(self.collection, id_, data) @@ -478,6 +496,19 @@ class EventsHandler(CollectionHandler): collection = 'events' object_id = 'event_id' + def filter_get(self, output): + if not self.has_permission('persons-all|read'): + if 'persons' in output: + output['persons'] = [] + return output + + def filter_get_all(self, output): + if not self.has_permission('persons-all|read'): + for event in output.get('events') or []: + if 'persons' in event: + event['persons'] = [] + return output + def _get_person_data(self, person_id_or_query, persons): """Filter a list of persons returning the first item with a given person_id or which set of keys specified in a dictionary match their respective values."""