Skip to content
Snippets Groups Projects
Commit 15f08e8d authored by Renzo Frigato's avatar Renzo Frigato
Browse files

check site permission for authorization

parent 71bbeba0
No related branches found
No related tags found
No related merge requests found
......@@ -16,10 +16,10 @@ ROLES = [
INTEGER_ROLES = {r['rid']: i for i, r in enumerate(ROLES)}
def _get_access(uid, container):
def _get_access(uid, site, container):
permissions_list = container.get('roles', container.get('permissions', []))
for perm in permissions_list:
if perm['_id'] == uid:
if perm['_id'] == uid and perm['site'] == site:
return INTEGER_ROLES[perm['access']]
else:
return -1
......
......@@ -20,21 +20,21 @@ def default_container(handler, container=None, target_parent_container=None):
if method == 'GET' and container.get('public', False):
has_access = True
elif method == 'GET':
has_access = _get_access(handler.uid, container) >= INTEGER_ROLES['ro']
has_access = _get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['ro']
elif method == 'POST':
has_access = _get_access(handler.uid, target_parent_container) >= INTEGER_ROLES['admin']
has_access = _get_access(handler.uid, handler.user_site, target_parent_container) >= INTEGER_ROLES['admin']
elif method == 'DELETE':
if target_parent_container:
has_access = _get_access(handler.uid, target_parent_container) >= INTEGER_ROLES['admin']
has_access = _get_access(handler.uid, handler.user_site, target_parent_container) >= INTEGER_ROLES['admin']
else:
has_access = _get_access(handler.uid, container) >= INTEGER_ROLES['admin']
has_access = _get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['admin']
elif method == 'PUT' and target_parent_container is not None:
has_access = (
_get_access(handler.uid, container) >= INTEGER_ROLES['admin'] and
_get_access(handler.uid, target_parent_container) >= INTEGER_ROLES['admin']
_get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['admin'] and
_get_access(handler.uid, handler.user_site, target_parent_container) >= INTEGER_ROLES['admin']
)
elif method == 'PUT' and target_parent_container is None:
has_access = _get_access(handler.uid, container) >= INTEGER_ROLES['rw']
has_access = _get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['rw']
else:
has_access = False
......@@ -56,13 +56,13 @@ def collection_permissions(handler, container=None, target_parent_container=None
if method == 'GET' and container.get('public', False):
has_access = True
elif method == 'GET':
has_access = _get_access(handler.uid, container) >= INTEGER_ROLES['ro']
has_access = _get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['ro']
elif method == 'DELETE':
has_access = _get_access(handler.uid, container) >= INTEGER_ROLES['admin']
has_access = _get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['admin']
elif method == 'POST':
has_access = True
elif method == 'PUT':
has_access = _get_access(handler.uid, container) >= INTEGER_ROLES['rw']
has_access = _get_access(handler.uid, handler.user_site, container) >= INTEGER_ROLES['rw']
else:
has_access = False
......@@ -91,10 +91,10 @@ def public_request(handler, container=None, parent_container=None):
def list_permission_checker(handler, admin_only=False):
def g(exec_op):
def f(method, query=None, user=None, public=False, projection=None):
handler_site = handler.source_site or handler.app.config['site_id']
handler_site = handler.user_site
if user and (user['_id'] != handler.uid or user['site'] != handler_site):
handler.abort(403, 'User ' + handler.uid + ' may not see the Projects of User ' + user['_id'])
query['permissions'] = {'$elemMatch': {'_id': handler.uid, 'site': handler.source_site or handler.app.config['site_id']}}
query['permissions'] = {'$elemMatch': {'_id': handler.uid, 'site': handler.user_site}}
if handler.is_true('public'):
query['$or'] = [{'public': True}, {'permissions': query.pop('permissions')}]
return exec_op(method, query=query, user=user, public=public, projection=projection)
......
......@@ -15,7 +15,7 @@ def default(handler, group=None):
handler.abort(400, 'public request is not valid')
elif method in ['DELETE', 'POST']:
handler.abort(403, 'not allowed to perform operation')
elif _get_access(handler.uid, group) >= INTEGER_ROLES['admin']:
elif _get_access(handler.uid, handler.user_site, group) >= INTEGER_ROLES['admin']:
pass
else:
handler.abort(403, 'not allowed to perform operation')
......
......@@ -16,7 +16,7 @@ def default_sublist(handler, container):
The resulting permissions checker modifies the exec_op method by checking the user permissions
on the container before actually executing this method.
"""
access = _get_access(handler.uid, container)
access = _get_access(handler.uid, handler.user_site, container)
def g(exec_op):
def f(method, _id, query_params=None, payload=None, exclude_params=None):
if method == 'GET' and container.get('public', False):
......@@ -39,7 +39,7 @@ def group_roles_sublist(handler, container):
"""
This is the customized permissions checker for group roles operations.
"""
access = _get_access(handler.uid, container)
access = _get_access(handler.uid, handler.user_site, container)
def g(exec_op):
def f(method, _id, query_params = None, payload = None, exclude_params=None):
if method in ['GET', 'DELETE'] and query_params.get('_id') == handler.uid:
......@@ -55,11 +55,11 @@ def permissions_sublist(handler, container):
"""
the customized permissions checker for permissions operations.
"""
access = _get_access(handler.uid, container)
access = _get_access(handler.uid, handler.user_site, container)
def g(exec_op):
def f(method, _id, query_params = None, payload = None, exclude_params=None):
log.debug(query_params)
if method in ['GET', 'DELETE'] and query_params.get('_id') == handler.uid and query_params.get('site') == (handler.source_site or handler.app.config['site_id']):
if method in ['GET', 'DELETE'] and query_params.get('_id') == handler.uid and query_params.get('site') == handler.user_site:
return exec_op(method, _id, query_params, payload, exclude_params)
elif access >= INTEGER_ROLES['admin']:
return exec_op(method, _id, query_params, payload, exclude_params)
......@@ -72,7 +72,7 @@ def notes_sublist(handler, container):
"""
permissions checker for notes_sublist
"""
access = _get_access(handler.uid, container)
access = _get_access(handler.uid, handler.user_site, container)
def g(exec_op):
def f(method, _id, query_params = None, payload = None, exclude_params=None):
if access >= INTEGER_ROLES['admin']:
......
import logging
import sys
import logging
log = logging.getLogger('scitran.api')
from . import _get_access, always_ok, INTEGER_ROLES
from . import always_ok, INTEGER_ROLES
def default(handler, user=None):
......
......@@ -88,6 +88,7 @@ class RequestHandler(webapp2.RequestHandler):
self.abort(402, remote_instance + ' is not an authorized remote instance')
else:
self.abort(401, 'no valid SSL client certificate')
self.user_site = self.source_site or self.app.config['site_id']
self.public_request = not drone_request and not self.uid
......
......@@ -36,7 +36,7 @@ class CollectionsHandler(ContainerHandler):
payload_validator(payload, 'POST')
payload['permissions'] = [{
'_id': self.uid,
'site': self.source_site or self.app.config['site_id'],
'site': self.user_site,
'access': 'admin'
}]
payload['created'] = payload['modified'] = datetime.datetime.utcnow()
......@@ -111,7 +111,7 @@ class CollectionsHandler(ContainerHandler):
results = permchecker(self.storage.exec_op)('GET', query=query, public=self.public_request, projection=projection)
if results is None:
self.abort(404, 'Element not found in collection {} {}'.format(storage.cont_name, _id))
self._filter_all_permissions(results, self.uid, self.source_site or self.app.config['site_id'])
self._filter_all_permissions(results, self.uid, self.user_site)
if self.is_true('counts'):
self._add_results_counts(results)
if self.debug:
......@@ -158,7 +158,7 @@ class CollectionsHandler(ContainerHandler):
log.debug(query)
log.debug(projection)
sessions = list(self.app.db.sessions.find(query, projection))
self._filter_all_permissions(sessions, self.uid, self.source_site or self.app.config['site_id'])
self._filter_all_permissions(sessions, self.uid, self.user_site)
if self.is_true('measurements'):
self._add_session_measurements(sessions)
if self.debug:
......@@ -188,7 +188,7 @@ class CollectionsHandler(ContainerHandler):
self.abort(400, sid + ' is not a valid ObjectId')
projection = self.container_handler_configurations['acquisitions']['list_projection']
acquisitions = list(self.app.db.acquisitions.find(query, projection))
self._filter_all_permissions(acquisitions, self.uid, self.source_site or self.app.config['site_id'])
self._filter_all_permissions(acquisitions, self.uid, self.user_site)
for acq in acquisitions:
acq.setdefault('timestamp', datetime.datetime.utcnow())
if self.debug:
......
......@@ -89,7 +89,7 @@ class ContainerHandler(base.RequestHandler):
if result is None:
self.abort(404, 'Element not found in container {} {}'.format(storage.cont_name, _id))
if not self.superuser_request:
self._filter_permissions(result, self.uid, self.source_site or self.app.config['site_id'])
self._filter_permissions(result, self.uid, self.user_site)
if self.is_true('paths'):
for fileinfo in result['files']:
fileinfo['path'] = str(_id)[-3:] + '/' + str(_id) + '/' + fileinfo['filename']
......@@ -124,7 +124,7 @@ class ContainerHandler(base.RequestHandler):
results = permchecker(self.storage.exec_op)('GET', query=query, public=self.public_request, projection=projection)
if results is None:
self.abort(404, 'Element not found in container {} {}'.format(storage.cont_name, _id))
self._filter_all_permissions(results, self.uid, self.source_site or self.app.config['site_id'])
self._filter_all_permissions(results, self.uid, self.user_site)
if self.is_true('counts'):
self._add_results_counts(results, cont_name)
if cont_name == 'sessions' and self.is_true('measurements'):
......@@ -182,7 +182,7 @@ class ContainerHandler(base.RequestHandler):
self.abort(400, e.message)
if results is None:
self.abort(404, 'Element not found in container {} {}'.format(storage.cont_name, _id))
self._filter_all_permissions(results, self.uid, self.source_site or self.app.config['site_id'])
self._filter_all_permissions(results, self.uid, self.user_site)
if self.debug:
debuginfo.add_debuginfo(self, cont_name, results)
return results
......@@ -202,7 +202,7 @@ class ContainerHandler(base.RequestHandler):
if self.is_true('inherit') and cont_name == 'projects':
payload['permissions'] = parent_container.get('roles')
elif cont_name =='projects':
payload['permissions'] = [{'_id': self.uid, 'access': 'admin'}]
payload['permissions'] = [{'_id': self.uid, 'access': 'admin', 'site': self.user_site}]
else:
payload['permissions'] = parent_container.get('permissions', [])
payload['created'] = payload['modified'] = datetime.datetime.utcnow()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment