diff --git a/collections_.py b/collections_.py index b05f442d228b3531c8ce4d69e8b401e1cc4092a4..11df8ce342f3e75f13f679c1848af860c825bd49 100644 --- a/collections_.py +++ b/collections_.py @@ -61,7 +61,18 @@ class Collections(nimsapiutil.NIMSRequestHandler): def post(self): """Create a new Collection.""" - self.response.write('collections post\n') + if not self.valid_parameters(): # FIXME: move to superclass init + self.abort(400, 'invalid parameters') + name = self.request.get('name') or 'innominate' + epoch_ids = [bson.ObjectId(eid) for eid in self.request.get_all('epochs[]', [])] + epochs = [self.app.db.epochs.find_one({'_id': eid}, ['session']) for eid in epoch_ids] + if not all(epochs): + self.abort(400, 'some Epoch IDs are invalid') + if not all([self.user_access_epoch(epoch) for epoch in epochs]): + self.abort(403, 'user does not have access to all Epochs') + cid = self.app.db.collections.insert({'curator': self.userid, 'name': name, 'permissions': {self.userid: 'admin'}}) + for eid in epoch_ids: + self.app.db.epochs.update({'_id': eid}, {'$push': {'collections': cid}}) def get(self): """Return the list of Collections.""" @@ -123,17 +134,44 @@ class Collection(nimsapiutil.NIMSRequestHandler): if not self.user_is_superuser: if self.userid not in collection['permissions']: self.abort(403) - if collection['permissions'][self.userid] != 'admin' and collection['permissions'][self.userid] != 'pi': + if collection['permissions'][self.userid] != 'admin': # mask other users' permissions collection['permissions'] = {self.userid: collection['permissions'][self.userid]} self.response.write(json.dumps(collection, default=bson.json_util.default)) def put(self, cid): """Update an existing Collection.""" - self.response.write('collection %s put, %s\n' % (exp_id, self.request.params)) + cid = bson.ObjectId(cid) + if not self.valid_parameters(): # FIXME: move to superclass init + self.abort(400, 'invalid parameters') + collection = self.app.db.collections.find_one({'_id': cid}) + if not collection: + self.abort(404, 'Collection not found') + if not self.user_is_superuser and collection['permissions'].get(self.userid) != 'admin': + self.abort(403, 'user must be admin on Collection to modify') + add_epoch_ids = [bson.ObjectId(eid) for eid in self.request.get_all('add_epochs[]', [])] + add_epochs = [self.app.db.epochs.find_one({'_id': eid}, ['session']) for eid in add_epoch_ids] + del_epoch_ids = [bson.ObjectId(eid) for eid in self.request.get_all('del_epochs[]', [])] + del_epochs = [self.app.db.epochs.find_one({'_id': eid}, ['session']) for eid in del_epoch_ids] + if not all(add_epochs + del_epochs): + self.abort(400, 'some Epoch IDs are invalid') + if not all([self.user_access_epoch(epoch) for epoch in add_epochs]): + self.abort(403, 'user does not have access to all Epochs') + for eid in add_epoch_ids: + print 'adding', eid, 'to', cid + self.app.db.epochs.update({'_id': eid}, {'$addToSet': {'collections': bson.ObjectId(cid)}}) + for eid in del_epoch_ids: + self.app.db.epochs.update({'_id': eid}, {'$pull': {'collections': bson.ObjectId(cid)}}) def delete(self, cid): """Delete a Collection.""" - self.abort(501) + cid = bson.ObjectId(cid) + collection = self.app.db.collections.find_one({'_id': cid}, ['permissions']) + if not collection: + self.abort(404, 'Collection not found') + if not self.user_is_superuser and collection['permissions'].get(self.userid) != 'admin': + self.abort(403, 'user must be admin on Collection to delete') + self.app.db.epochs.update({'collections': cid}, {'$pull': {'collections': cid}}, multi=True) + self.app.db.collections.remove({'_id': cid}) class Sessions(nimsapiutil.NIMSRequestHandler): diff --git a/experiments.py b/experiments.py index 8ece9d1281b774c94703643bd66b1dcf8d27a698..cfe463c285db49c70e018dbca74b0a7f86534c21 100644 --- a/experiments.py +++ b/experiments.py @@ -368,16 +368,12 @@ class Epoch(nimsapiutil.NIMSRequestHandler): def get(self, eid): """Return one Epoch, conditionally with details.""" + if not self.valid_parameters(): + self.abort(400, 'invalid parameters') epoch = self.app.db.epochs.find_one({'_id': bson.ObjectId(eid)}) if not epoch: self.abort(404) - session = self.app.db.sessions.find_one({'_id': epoch['session']}) - if not session: - self.abort(500) - experiment = self.app.db.experiments.find_one({'_id': session['experiment']}) - if not experiment: - self.abort(500) - if not self.user_is_superuser and self.userid not in experiment['permissions']: + if not self.user_access_epoch(epoch): self.abort(403) self.response.write(json.dumps(epoch, default=bson.json_util.default)) diff --git a/nimsapi.py b/nimsapi.py index bf2c91e92f3805c17234e750a7af0c7314ae0af7..5ee8063ce4c498845f76f08ab45b373f952a8a65 100755 --- a/nimsapi.py +++ b/nimsapi.py @@ -475,7 +475,7 @@ if __name__ == '__main__': else: log.warning('private SSL key not specified, internims functionality disabled') - app.config['site_id'] = args.site_id + app.config['site_id'] = args.site_id or 'local' app.config['stage_path'] = args.stage_path or config.get('nims', 'stage_path') db_uri = args.db_uri or config.get('nims', 'db_uri') diff --git a/nimsapiutil.py b/nimsapiutil.py index 83eb2fd0d54d034a7c772b88059837b57c9bf45a..13be4a2a8894909d5e9821defba79c9c7387cd71 100644 --- a/nimsapiutil.py +++ b/nimsapiutil.py @@ -61,10 +61,7 @@ class NIMSRequestHandler(webapp2.RequestHandler): if not self.request.path.endswith('/nimsapi/log'): # TODO: change to log.debug - log.info(self.request.method + ' ' + self.request.path) - log.info('params: ' + str(self.request.params.mixed())) - log.info('headers: ' + str(dict(self.request.headers))) - + log.info(self.request.method + ' ' + self.request.path + ' ' + str(self.request.params.mixed())) def dispatch(self): """dispatching and request forwarding""" @@ -129,3 +126,18 @@ class NIMSRequestHandler(webapp2.RequestHandler): def schema(self, *args, **kwargs): self.response.write(json.dumps(self.json_schema, default=bson.json_util.default)) + + def valid_parameters(self): + # FIXME: implement, using self.request.params.mixed() + return True + + def user_access_epoch(self, epoch): + if self.user_is_superuser: + return True + session = self.app.db.sessions.find_one({'_id': epoch['session']}) + if not session: + self.abort(500) + experiment = self.app.db.experiments.find_one({'_id': session['experiment']}) + if not experiment: + self.abort(500) + return (self.userid in experiment['permissions'])