Commit 173ab13a authored by Alejandro Alvarez Ayllon's avatar Alejandro Alvarez Ayllon
Browse files

FTS-408: Consult roles for job listing

parent 0dc5756f
......@@ -30,6 +30,7 @@ from fts3rest.lib.JobBuilder import get_storage_element
from fts3rest.lib.helpers import jsonify
from fts3rest.lib.middleware.fts3auth import authorize
from fts3rest.lib.middleware.fts3auth.constants import *
from fts3rest.lib.http_exceptions import *
log = logging.getLogger(__name__)
......@@ -56,6 +57,8 @@ class FilesController(BaseController):
"""
Get a list of active jobs, or those that match the filter requirements
"""
user = request.environ['fts3.User.Credentials']
filter_vo = request.params.get('vo_name', None)
filter_state = request.params.get('state_in', None)
filter_source = request.params.get('source_se', None)
......@@ -78,6 +81,13 @@ class FilesController(BaseController):
if filter_dest is None and filter_dest_surl is not None:
filter_dest = get_storage_element(urlparse(filter_dest_surl))
# Automatically apply filters depending on granted level
granted_level = user.get_granted_level_for(TRANSFER)
if granted_level in (PRIVATE, VO):
filter_vo = user.vos[0]
elif granted_level == NONE:
raise HTTPForbidden('User not allowed to list jobs')
files = Session.query(File)
if filter_vo:
files = files.filter(File.vo_name == filter_vo)
......
......@@ -123,13 +123,20 @@ class JobsController(BaseController):
if filter_dlg_id and filter_dlg_id != user.delegation_id:
raise HTTPForbidden('The provided delegation id does not match your delegation id')
if filter_dlg_id and filter_dn and filter_dn != user.user_dn:
if filter_dn and filter_dn != user.user_dn:
raise HTTPBadRequest('The provided DN and delegation id do not correspond to the same user')
if not filter_dlg_id and filter_state:
raise HTTPForbidden('To filter by state, you need to provide dlg_id')
if filter_limit is not None and filter_limit < 0 or filter_limit > 500:
raise HTTPBadRequest('The limit must be positive and less or equal than 500')
# Automatically apply filters depending on granted level
granted_level = user.get_granted_level_for(TRANSFER)
if granted_level == PRIVATE:
filter_dlg_id = user.delegation_id
elif granted_level == VO:
filter_vo = user.vos[0]
elif granted_level == NONE:
raise HTTPForbidden('User not allowed to list jobs')
if filter_state:
filter_state = filter_state.split(',')
jobs = jobs.filter(Job.job_state.in_(filter_state))
......
......@@ -20,7 +20,7 @@ from datetime import datetime, timedelta
from fts3.model import FileRetryLog, Job, File
from fts3rest.lib.base import Session
from fts3rest.lib.middleware.fts3auth import UserCredentials
from fts3rest.lib.middleware.fts3auth import UserCredentials, constants
from fts3rest.tests import TestController
......@@ -266,19 +266,6 @@ class TestJobListing(TestController):
).json
self.assertTrue(job_id not in map(lambda j: j['job_id'], job_list))
def test_list_with_state_no_dlg_id(self):
"""
When specifying the statuses in the query, dlg_id is mandatory
"""
self.setup_gridsite_environment()
self.push_delegation()
self.app.get(
url="/jobs",
params={'state_in': 'SUBMITTED,ACTIVE'},
status=403
)
def test_list_no_vo(self):
"""
Submit a valid job with no VO data in the credentials. Listing it should be possible
......@@ -571,3 +558,63 @@ class TestJobListing(TestController):
self.assertIn(job1, map(lambda f: f['job_id'], files))
self.assertNotIn(job2, map(lambda f: f['job_id'], files))
def test_list_granted_private(self):
"""
Configure access level to PRIVATE, so the user can only see their own transfers
"""
self.setup_gridsite_environment(dn='/CN=fakeson')
self.push_delegation()
self._submit()
self._submit()
self.setup_gridsite_environment()
self.push_delegation()
job3 = self._submit()
old_granted = UserCredentials.get_granted_level_for
UserCredentials.get_granted_level_for = lambda self_, op: constants.PRIVATE
jobs = self.app.get(url="/jobs", status=200).json
UserCredentials.get_granted_level_for = old_granted
self.assertEqual(1, len(jobs))
self.assertEqual(job3, jobs[0]['job_id'])
def test_list_granted_vo(self):
"""
Configure access level to VO, so the user can see their own transfers and others, if they
belong to the same vo
"""
self.setup_gridsite_environment(dn='/CN=fakeson', no_vo=True)
self.push_delegation()
self._submit()
self._submit()
self.setup_gridsite_environment(dn='/CN=jameson')
self.push_delegation()
job1 = self._submit()
job2 = self._submit()
self.setup_gridsite_environment()
self.push_delegation()
job3 = self._submit()
old_granted = UserCredentials.get_granted_level_for
UserCredentials.get_granted_level_for = lambda self_, op: constants.VO
jobs = self.app.get(url="/jobs", status=200).json
UserCredentials.get_granted_level_for = old_granted
self.assertEqual(3, len(jobs))
job_ids = map(lambda j: j['job_id'], jobs)
self.assertIn(job1, job_ids)
self.assertIn(job2, job_ids)
self.assertIn(job3, job_ids)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment