diff --git a/epochs.py b/epochs.py index b90c1b5b31cd01728d1dd73ac58f50a7d66095bb..18d46f690229a0246e51423a236131f957087161 100644 --- a/epochs.py +++ b/epochs.py @@ -19,15 +19,13 @@ class Epochs(nimsapiutil.NIMSRequestHandler): def get(self, sess_id): """Return the list of Session Epochs.""" - self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER - user = self.request.remote_user or '@public' session = self.app.db.sessions.find_one({'_id': bson.objectid.ObjectId(sess_id)}) if not session: self.abort(404) experiment = self.app.db.experiments.find_one({'_id': bson.objectid.ObjectId(session['experiment'])}) if not experiment: self.abort(500) - if user not in experiment['permissions']: + if not self.user_is_superuser and self.userid not in experiment['permissions']: self.abort(403) query = {'session': bson.objectid.ObjectId(sess_id)} projection = ['timestamp', 'series', 'acquisition', 'description', 'datatype'] @@ -43,8 +41,6 @@ class Epoch(nimsapiutil.NIMSRequestHandler): def get(self, epoch_id): """Return one Epoch, conditionally with details.""" - self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER - user = self.request.remote_user or '@public' epoch = self.app.db.epochs.find_one({'_id': bson.objectid.ObjectId(epoch_id)}) if not epoch: self.abort(404) @@ -54,7 +50,7 @@ class Epoch(nimsapiutil.NIMSRequestHandler): experiment = self.app.db.experiments.find_one({'_id': bson.objectid.ObjectId(session['experiment'])}) if not experiment: self.abort(500) - if user not in experiment['permissions']: + if not self.user_is_superuser and self.userid not in experiment['permissions']: self.abort(403) self.response.write(json.dumps(epoch, default=bson.json_util.default)) diff --git a/experiments.py b/experiments.py index 18f5cf826b110e5425bc81483ec36bbbc52aa8dd..ea6e9c47399efdd92a8f2ceddec56ae6b8995c38 100644 --- a/experiments.py +++ b/experiments.py @@ -19,10 +19,8 @@ class Experiments(nimsapiutil.NIMSRequestHandler): def get(self): """Return the list of Experiments.""" - self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER - user = self.request.remote_user or '@public' - query = {'permissions.' + user: {'$exists': 'true'}} - projection = ['timestamp', 'group', 'name', 'permissions.'+user] + query = {'permissions.' + self.userid: {'$exists': 'true'}} if not self.user_is_superuser else None + projection = ['timestamp', 'group', 'name', 'permissions.'+self.userid] experiments = list(self.app.db.experiments.find(query, projection)) self.response.write(json.dumps(experiments, default=bson.json_util.default)) @@ -35,16 +33,14 @@ class Experiment(nimsapiutil.NIMSRequestHandler): def get(self, exp_id): """Return one Experiment, conditionally with details.""" - self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER - user = self.request.remote_user or '@public' - query = {'_id': bson.objectid.ObjectId(exp_id), 'permissions.' + user: {'$exists': 'true'}} experiment = self.app.db.experiments.find_one({'_id': bson.objectid.ObjectId(exp_id)}) if not experiment: self.abort(404) - if user not in experiment['permissions']: - self.abort(403) - if experiment['permissions'][user] != 'admin' and experiment['permissions'][user] != 'pi': - experiment['permissions'] = {user: experiment['permissions'][user]} + if not self.user_is_superuser: + if self.userid not in experiment['permissions']: + self.abort(403) + if experiment['permissions'][self.userid] != 'admin' and experiment['permissions'][self.userid] != 'pi': + experiment['permissions'] = {self.userid: experiment['permissions'][self.userid]} self.response.write(json.dumps(experiment, default=bson.json_util.default)) def put(self, exp_id): diff --git a/nimsapi.py b/nimsapi.py index e24b8a0b50093cd0a6511da4bd21fe88148167bd..df2ee703b7c5ea1b0dee1fe7c41f2d74b31d85b8 100755 --- a/nimsapi.py +++ b/nimsapi.py @@ -88,7 +88,25 @@ class User(nimsapiutil.NIMSRequestHandler): def put(self, uid): """Update an existing User.""" - self.response.write('user %s put, %s\n' % (uid, self.request.params)) + user = self.app.db.users.find_one({'_id': uid}) + if not user: + self.abort(404) + if uid == self.userid or self.user_is_superuser: # users can only update their own info + updates = {'$set': {}, '$unset': {}} + for k, v in self.request.params.iteritems(): + if k != 'superuser' and k in user_fields: + updates['$set'][k] = v # FIXME: do appropriate type conversion + elif k == 'superuser' and uid == self.userid and self.user_is_superuser is not None: # toggle superuser for requesting user + updates['$set'][k] = v.lower() in ('1', 'true') + elif k == 'superuser' and uid != self.userid and self.user_is_superuser: # enable/disable superuser for other user + if v.lower() in ('1', 'true') and user.get('superuser') is None: + updates['$set'][k] = False # superuser is tri-state: False indicates granted, but disabled, superuser privileges + elif v.lower() not in ('1', 'true'): + updates['$unset'][k] = '' + user = self.app.db.users.find_and_modify({'_id': uid}, updates, new=True) + else: + self.abort(403) + self.response.write(json.dumps(user, default=bson.json_util.default) + '\n') def delete(self, uid): """Delete an User.""" diff --git a/nimsapiutil.py b/nimsapiutil.py index ec4691cde561bdf14029ef61eb803b7c1d03552f..c4acbcafc0b725f6c21bcefb392ebd9f76de8adc 100644 --- a/nimsapiutil.py +++ b/nimsapiutil.py @@ -7,4 +7,8 @@ class NIMSRequestHandler(webapp2.RequestHandler): def __init__(self, request=None, response=None): webapp2.RequestHandler.__init__(self, request, response) + self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER + self.userid = self.request.remote_user or '@public' + self.user = self.app.db.users.find_one({'_id': self.userid}) + self.user_is_superuser = self.user.get('superuser') self.response.headers['Content-Type'] = 'application/json' diff --git a/sessions.py b/sessions.py index e1349062218ef90bcb5458ed6d4fedb8dc8678b5..d79f6bb454cf18d37e24728ffee0fd8b0c9afd87 100644 --- a/sessions.py +++ b/sessions.py @@ -19,12 +19,10 @@ class Sessions(nimsapiutil.NIMSRequestHandler): def get(self, exp_id): """Return the list of Experiment Sessions.""" - self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER - user = self.request.remote_user or '@public' experiment = self.app.db.experiments.find_one({'_id': bson.objectid.ObjectId(exp_id)}) if not experiment: self.abort(404) - if user not in experiment['permissions']: + if not self.user_is_superuser and self.userid not in experiment['permissions']: self.abort(403) query = {'experiment': bson.objectid.ObjectId(exp_id)} projection = ['timestamp', 'subject'] @@ -40,15 +38,13 @@ class Session(nimsapiutil.NIMSRequestHandler): def get(self, sess_id): """Return one Session, conditionally with details.""" - self.request.remote_user = self.request.get('user', None) # FIXME: auth system should set REMOTE_USER - user = self.request.remote_user or '@public' session = self.app.db.sessions.find_one({'_id': bson.objectid.ObjectId(sess_id)}) if not session: self.abort(404) experiment = self.app.db.experiments.find_one({'_id': bson.objectid.ObjectId(session['experiment'])}) if not experiment: self.abort(500) - if user not in experiment['permissions']: + if not self.user_is_superuser and self.userid not in experiment['permissions']: self.abort(403) self.response.write(json.dumps(session, default=bson.json_util.default))