Fix export job (#5282)

main
Kirill Sizov 3 years ago committed by GitHub
parent c86746c785
commit 25503a35d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -76,6 +76,7 @@ non-ascii paths while adding files from "Connected file share" (issue #4428)
- Oriented bounding boxes broken with COCO format ss(<https://github.com/opencv/cvat/pull/5219>)
- Fixed upload resumption in production environments
(<https://github.com/opencv/cvat/issues/4839>)
- Fixed job exporting (<https://github.com/opencv/cvat/pull/5282>)
- Visibility and ignored information fail to be loaded (MOT dataset format) (<https://github.com/opencv/cvat/pull/5270>)
### Security

@ -892,6 +892,7 @@ class JobPermission(OpenPolicyAgentPermission):
('update', 'PUT'): 'update', # TODO: do we need the method?
('destroy', 'DELETE'): 'delete',
('annotations', 'GET'): 'view:annotations',
('dataset_export', 'GET'): 'export:dataset',
('annotations', 'PATCH'): 'update:annotations',
('annotations', 'DELETE'): 'delete:annotations',
('annotations', 'PUT'): 'update:annotations',

@ -21,6 +21,14 @@ view:annotations,Job,Sandbox,None,,GET,/jobs/{id}/annotations,Admin,N/A
view:annotations,Job,Sandbox,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,GET,/jobs/{id}/annotations,None,N/A
view:annotations,Job,Organization,None,,GET,/jobs/{id}/annotations,User,Maintainer
view:annotations,Job,Organization,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,GET,/jobs/{id}/annotations,None,Worker
export:annotations,Job,Sandbox,None,,GET,/jobs/{id}/annotations?format={format},Admin,N/A
export:annotations,Job,Sandbox,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,GET,/jobs/{id}/annotations?format={format},None,N/A
export:annotations,Job,Organization,None,,GET,/jobs/{id}/annotations?format={format},User,Maintainer
export:annotations,Job,Organization,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,GET,/jobs/{id}/annotations?format={format},None,Worker
export:dataset,Job,Sandbox,None,,GET,/jobs/{id}/dataset,Admin,N/A
export:dataset,Job,Sandbox,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,GET,/jobs/{id}/dataset,None,N/A
export:dataset,Job,Organization,None,,GET,/jobs/{id}/dataset,User,Maintainer
export:dataset,Job,Organization,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,GET,/jobs/{id}/dataset,None,Worker
update:annotations,Job,Sandbox,None,,PATCH,/jobs/{id}/annotations,Admin,N/A
update:annotations,Job,Sandbox,"Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee",,PATCH,/jobs/{id}/annotations,Worker,N/A
update:annotations,Job,Organization,None,,PATCH,/jobs/{id}/annotations,User,Maintainer

1 Scope Resource Context Ownership Limit Method URL Privilege Membership
21 view:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/annotations None N/A
22 view:annotations Job Organization None GET /jobs/{id}/annotations User Maintainer
23 view:annotations Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/annotations None Worker
24 export:annotations Job Sandbox None GET /jobs/{id}/annotations?format={format} Admin N/A
25 export:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/annotations?format={format} None N/A
26 export:annotations Job Organization None GET /jobs/{id}/annotations?format={format} User Maintainer
27 export:annotations Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/annotations?format={format} None Worker
28 export:dataset Job Sandbox None GET /jobs/{id}/dataset Admin N/A
29 export:dataset Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/dataset None N/A
30 export:dataset Job Organization None GET /jobs/{id}/dataset User Maintainer
31 export:dataset Job Organization Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee GET /jobs/{id}/dataset None Worker
32 update:annotations Job Sandbox None PATCH /jobs/{id}/annotations Admin N/A
33 update:annotations Job Sandbox Project:owner, Project:assignee, Task:owner, Task:assignee, Assignee PATCH /jobs/{id}/annotations Worker N/A
34 update:annotations Job Organization None PATCH /jobs/{id}/annotations User Maintainer

@ -4,7 +4,8 @@ import data.organizations
# input: {
# "scope": <"view"|"list"|"update:state"|"update:stage"|"update:assignee""delete"|
# "view:annotations"|"update:annotations"|"delete:annotations"|"view:data"> or null,
# "view:annotations"|"update:annotations"|"delete:annotations"|"view:data"|
# "export:annotations" | "export:dataset" |> or null,
# "auth": {
# "user": {
# "id": <num>,
@ -139,20 +140,20 @@ filter = [] { # Django Q object to filter list of entries
}
allow {
{ utils.VIEW, utils.VIEW_ANNOTATIONS, utils.VIEW_DATA, utils.VIEW_METADATA, utils.VIEW_COMMITS }[input.scope]
{ utils.VIEW, utils.EXPORT_DATASET, utils.EXPORT_ANNOTATIONS, utils.VIEW_ANNOTATIONS, utils.VIEW_DATA, utils.VIEW_METADATA, utils.VIEW_COMMITS }[input.scope]
utils.is_sandbox
is_job_staff
}
allow {
{ utils.VIEW, utils.VIEW_ANNOTATIONS, utils.VIEW_DATA, utils.VIEW_METADATA, utils.VIEW_COMMITS }[input.scope]
{ utils.VIEW, utils.EXPORT_DATASET, utils.EXPORT_ANNOTATIONS, utils.VIEW_ANNOTATIONS, utils.VIEW_DATA, utils.VIEW_METADATA, utils.VIEW_COMMITS }[input.scope]
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.USER)
organizations.has_perm(organizations.MAINTAINER)
}
allow {
{ utils.VIEW, utils.VIEW_ANNOTATIONS, utils.VIEW_DATA, utils.VIEW_METADATA, utils.VIEW_COMMITS }[input.scope]
{ utils.VIEW, utils.EXPORT_DATASET, utils.EXPORT_ANNOTATIONS, utils.VIEW_ANNOTATIONS, utils.VIEW_DATA, utils.VIEW_METADATA, utils.VIEW_COMMITS }[input.scope]
input.auth.organization.id == input.resource.organization.id
organizations.has_perm(organizations.WORKER)
is_job_staff

File diff suppressed because it is too large Load Diff

@ -539,9 +539,30 @@ class TestJobDataset:
response = self._export_dataset(admin_user, job["id"], format="CVAT for images 1.1")
assert response.data
def test_can_export_annotations(self, admin_user: str, jobs_with_shapes: List):
job = jobs_with_shapes[0]
response = self._export_annotations(admin_user, job["id"], format="CVAT for images 1.1")
def test_non_admin_can_export_dataset(self, users, tasks, jobs_with_shapes):
job_id, username = next(
(
(job["id"], tasks[job["task_id"]]["owner"]["username"])
for job in jobs_with_shapes
if "admin" not in users[tasks[job["task_id"]]["owner"]["id"]]["groups"]
and tasks[job["task_id"]]["target_storage"] is None
and tasks[job["task_id"]]["organization"] is None
)
)
response = self._export_dataset(username, job_id, format="CVAT for images 1.1")
assert response.data
def test_non_admin_can_export_annotations(self, users, tasks, jobs_with_shapes):
job_id, username = next(
(
(job["id"], tasks[job["task_id"]]["owner"]["username"])
for job in jobs_with_shapes
if "admin" not in users[tasks[job["task_id"]]["owner"]["id"]]["groups"]
and tasks[job["task_id"]]["target_storage"] is None
and tasks[job["task_id"]]["organization"] is None
)
)
response = self._export_annotations(username, job_id, format="CVAT for images 1.1")
assert response.data
@pytest.mark.parametrize("username, jid", [("admin1", 14)])

Loading…
Cancel
Save