Skip to content
This repository was archived by the owner on Nov 14, 2023. It is now read-only.

Commit 4c5372c

Browse files
zhiltsov-maxmikhail-treskin
authored andcommitted
Add job access checks for model invocations (cvat-ai#5392)
Fixes cvat-ai#4996 - Added job access checks for model launches in the interactive mode
1 parent bf8b1b5 commit 4c5372c

File tree

6 files changed

+272
-37
lines changed

6 files changed

+272
-37
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ non-ascii paths while adding files from "Connected file share" (issue #4428)
9090
- Fixed FBRS serverless function runtime error on images with alpha channel (<https://github.com/opencv/cvat/pull/5384>)
9191
- Attaching manifest with custom name (<https://github.com/opencv/cvat/pull/5377>)
9292
- Uploading non-zip annotaion files (<https://github.com/opencv/cvat/pull/5386>)
93+
- A permission problem with interactive model launches for workers in orgs (<https://github.com/opencv/cvat/issues/4996>)
9394
- Fix chart not being upgradable (<https://github.com/opencv/cvat/pull/5371>)
9495
- Broken helm chart - if using custom release name (<https://github.com/opencv/cvat/pull/5403>)
9596
- Missing source tag in project annotations (<https://github.com/opencv/cvat/pull/5408>)

cvat-ui/src/components/annotation-page/standard-workspace/controls-side-bar/tools-control.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ export class ToolsControlComponent extends React.PureComponent<Props, State> {
369369
try {
370370
// run server request
371371
this.setState({ fetching: true });
372-
const response = await core.lambda.call(jobInstance.taskId, interactor, data);
372+
const response = await core.lambda.call(jobInstance.taskId, interactor,
373+
{ ...data, job: jobInstance.id });
373374

374375
// approximation with cv.approxPolyDP
375376
const approximated = await this.approximateResponsePoints(response.points);
@@ -740,6 +741,7 @@ export class ToolsControlComponent extends React.PureComponent<Props, State> {
740741
const response = await core.lambda.call(jobInstance.taskId, tracker, {
741742
frame: frame - 1,
742743
shapes: trackableObjects.shapes,
744+
job: jobInstance.id,
743745
});
744746

745747
const { states: serverlessStates } = response;
@@ -787,6 +789,7 @@ export class ToolsControlComponent extends React.PureComponent<Props, State> {
787789
frame,
788790
shapes: trackableObjects.shapes,
789791
states: trackableObjects.states,
792+
job: jobInstance.id,
790793
});
791794

792795
response.shapes = response.shapes.map(trackedRectangleMapper);
@@ -1161,7 +1164,9 @@ export class ToolsControlComponent extends React.PureComponent<Props, State> {
11611164
runInference={async (model: Model, body: DetectorRequestBody) => {
11621165
try {
11631166
this.setState({ mode: 'detection', fetching: true });
1164-
const result = await core.lambda.call(jobInstance.taskId, model, { ...body, frame });
1167+
const result = await core.lambda.call(jobInstance.taskId, model, {
1168+
...body, frame, job: jobInstance.id,
1169+
});
11651170
const states = result.map(
11661171
(data: any): any => {
11671172
const jobLabel = (jobInstance.labels as Label[])

cvat/apps/engine/models.py

+8
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,9 @@ class Segment(models.Model):
446446
start_frame = models.IntegerField()
447447
stop_frame = models.IntegerField()
448448

449+
def contains_frame(self, idx: int) -> bool:
450+
return self.start_frame <= idx and idx <= self.stop_frame
451+
449452
class Meta:
450453
default_permissions = ()
451454

@@ -472,6 +475,11 @@ def get_project_id(self):
472475
project = self.segment.task.project
473476
return project.id if project else None
474477

478+
@extend_schema_field(OpenApiTypes.INT)
479+
def get_task_id(self):
480+
task = self.segment.task
481+
return task.id if task else None
482+
475483
def get_organization_id(self):
476484
return self.segment.task.organization
477485

cvat/apps/iam/permissions.py

+14-3
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,15 @@ class LambdaPermission(OpenPolicyAgentPermission):
365365
def create(cls, request, view, obj):
366366
permissions = []
367367
if view.basename == 'function' or view.basename == 'request':
368-
for scope in cls.get_scopes(request, view, obj):
368+
scopes = cls.get_scopes(request, view, obj)
369+
for scope in scopes:
369370
self = cls.create_base_perm(request, view, scope, obj)
370371
permissions.append(self)
371372

372-
task_id = request.data.get('task')
373-
if task_id:
373+
if job_id := request.data.get('job'):
374+
perm = JobPermission.create_scope_view_data(request, job_id)
375+
permissions.append(perm)
376+
elif task_id := request.data.get('task'):
374377
perm = TaskPermission.create_scope_view_data(request, task_id)
375378
permissions.append(perm)
376379

@@ -879,6 +882,14 @@ def create(cls, request, view, obj):
879882

880883
return permissions
881884

885+
@classmethod
886+
def create_scope_view_data(cls, request, job_id):
887+
try:
888+
obj = Job.objects.get(id=job_id)
889+
except Job.DoesNotExist as ex:
890+
raise ValidationError(str(ex))
891+
return cls(**cls.unpack_context(request), obj=obj, scope='view:data')
892+
882893
def __init__(self, **kwargs):
883894
super().__init__(**kwargs)
884895
self.url = settings.IAM_OPA_DATA_URL + '/jobs/allow'

0 commit comments

Comments
 (0)