Skip to content

Commit

Permalink
Merge pull request #8473 from cvat-ai/release-2.19.1
Browse files Browse the repository at this point in the history
Release v2.19.1
  • Loading branch information
cvat-bot[bot] authored Sep 26, 2024
2 parents f316494 + 6bf8096 commit 4163cb2
Show file tree
Hide file tree
Showing 19 changed files with 119 additions and 42 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- scriv-insert-here -->

<a id='changelog-2.19.1'></a>
## \[2.19.1\] - 2024-09-26

### Security

- Fixed a security issue that occurred in PATCH requests to projects|tasks|jobs|memberships
(<https://github.com/cvat-ai/cvat/security/advisories/GHSA-gxhm-hg65-5gh2>)

<a id='changelog-2.19.0'></a>
## \[2.19.0\] - 2024-09-20

Expand Down
2 changes: 1 addition & 1 deletion cvat-cli/requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
cvat-sdk~=2.19.0
cvat-sdk~=2.19.1
Pillow>=10.3.0
setuptools>=70.0.0 # not directly required, pinned by Snyk to avoid a vulnerability
2 changes: 1 addition & 1 deletion cvat-cli/src/cvat_cli/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "2.19.0"
VERSION = "2.19.1"
2 changes: 1 addition & 1 deletion cvat-sdk/gen/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set -e

GENERATOR_VERSION="v6.0.1"

VERSION="2.19.0"
VERSION="2.19.1"
LIB_NAME="cvat_sdk"
LAYER1_LIB_NAME="${LIB_NAME}/api_client"
DST_DIR="$(cd "$(dirname -- "$0")/.." && pwd)"
Expand Down
2 changes: 1 addition & 1 deletion cvat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

from cvat.utils.version import get_version

VERSION = (2, 19, 0, 'final', 0)
VERSION = (2, 19, 1, 'final', 0)

__version__ = get_version(VERSION)
30 changes: 17 additions & 13 deletions cvat/apps/engine/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ class Scopes(StrEnum):
UPDATE_ASSIGNEE = 'update:assignee'
UPDATE_DESC = 'update:desc'
UPDATE_ORG = 'update:organization'
UPDATE_ASSOCIATED_STORAGE = 'update:associated_storage'
VIEW = 'view'
IMPORT_DATASET = 'import:dataset'
EXPORT_ANNOTATIONS = 'export:annotations'
Expand Down Expand Up @@ -285,6 +286,9 @@ def get_scopes(request, view, obj):

scopes = []
if scope == Scopes.UPDATE:
# user should have permissions to view a project
scopes.append(Scopes.VIEW)

if any(k in request.data for k in ('owner_id', 'owner')):
owner_id = request.data.get('owner_id') or request.data.get('owner')
if owner_id != getattr(obj.owner, 'id', None):
Expand All @@ -299,6 +303,9 @@ def get_scopes(request, view, obj):
break
if 'organization' in request.data:
scopes.append(Scopes.UPDATE_ORG)

if {'source_storage', 'target_storage'} & request.data.keys():
scopes.append(Scopes.UPDATE_ASSOCIATED_STORAGE)
else:
scopes.append(scope)

Expand Down Expand Up @@ -376,6 +383,7 @@ class Scopes(StrEnum):
UPDATE_ASSIGNEE = 'update:assignee'
UPDATE_PROJECT = 'update:project'
UPDATE_OWNER = 'update:owner'
UPDATE_ASSOCIATED_STORAGE = 'update:associated_storage'
DELETE = 'delete'
VIEW_ANNOTATIONS = 'view:annotations'
UPDATE_ANNOTATIONS = 'update:annotations'
Expand Down Expand Up @@ -509,6 +517,8 @@ def get_scopes(request, view, obj) -> List[Scopes]:
scopes.append(scope)

elif scope == Scopes.UPDATE:
# user should have permissions to view a task
scopes.append(Scopes.VIEW)
if any(k in request.data for k in ('owner_id', 'owner')):
owner_id = request.data.get('owner_id') or request.data.get('owner')
if owner_id != getattr(obj.owner, 'id', None):
Expand All @@ -530,6 +540,9 @@ def get_scopes(request, view, obj) -> List[Scopes]:
if request.data.get('organization'):
scopes.append(Scopes.UPDATE_ORGANIZATION)

if {'source_storage', 'target_storage'} & request.data.keys():
scopes.append(Scopes.UPDATE_ASSOCIATED_STORAGE)

elif scope == Scopes.VIEW_ANNOTATIONS:
if 'format' in request.query_params:
scope = Scopes.EXPORT_ANNOTATIONS
Expand Down Expand Up @@ -614,11 +627,8 @@ class Scopes(StrEnum):
VIEW = 'view'
UPDATE = 'update'
UPDATE_ASSIGNEE = 'update:assignee'
UPDATE_OWNER = 'update:owner'
UPDATE_PROJECT = 'update:project'
UPDATE_STAGE = 'update:stage'
UPDATE_STATE = 'update:state'
UPDATE_DESC = 'update:desc'
DELETE = 'delete'
VIEW_ANNOTATIONS = 'view:annotations'
UPDATE_ANNOTATIONS = 'update:annotations'
Expand Down Expand Up @@ -728,25 +738,19 @@ def get_scopes(request, view, obj):

scopes = []
if scope == Scopes.UPDATE:
if any(k in request.data for k in ('owner_id', 'owner')):
owner_id = request.data.get('owner_id') or request.data.get('owner')
if owner_id != getattr(obj.owner, 'id', None):
scopes.append(Scopes.UPDATE_OWNER)
# user should have permissions to view a job
scopes.append(Scopes.VIEW)

if any(k in request.data for k in ('assignee_id', 'assignee')):
assignee_id = request.data.get('assignee_id') or request.data.get('assignee')
if assignee_id != getattr(obj.assignee, 'id', None):
scopes.append(Scopes.UPDATE_ASSIGNEE)
if any(k in request.data for k in ('project_id', 'project')):
project_id = request.data.get('project_id') or request.data.get('project')
if project_id != getattr(obj.project, 'id', None):
scopes.append(Scopes.UPDATE_PROJECT)

if 'stage' in request.data:
scopes.append(Scopes.UPDATE_STAGE)
if 'state' in request.data:
scopes.append(Scopes.UPDATE_STATE)

if any(k in request.data for k in ('name', 'labels', 'bug_tracker', 'subset')):
scopes.append(Scopes.UPDATE_DESC)
elif scope == Scopes.VIEW_ANNOTATIONS:
if 'format' in request.query_params:
scope = Scopes.EXPORT_ANNOTATIONS
Expand Down
8 changes: 4 additions & 4 deletions cvat/apps/engine/rules/projects.rego
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import data.organizations

# input: {
# "scope": <"create"|"list"|"update:desc"|"update:owner"|"update:assignee"|
# "view"|"delete"|"export:dataset"|"export:annotations"|
# "update:associated_storage"|"view"|"delete"|"export:dataset"|"export:annotations"|
# "import:dataset"> or null,
# "auth": {
# "user": {
Expand Down Expand Up @@ -127,22 +127,22 @@ allow if {


allow if {
input.scope in {utils.DELETE, utils.UPDATE_ORG}
input.scope in {utils.DELETE, utils.UPDATE_ORG, utils.UPDATE_ASSOCIATED_STORAGE}
utils.is_sandbox
utils.has_perm(utils.WORKER)
utils.is_resource_owner
}

allow if {
input.scope in {utils.DELETE, utils.UPDATE_ORG}
input.scope in {utils.DELETE, utils.UPDATE_ORG, utils.UPDATE_ASSOCIATED_STORAGE}
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.WORKER)
organizations.is_member
utils.is_resource_owner
}

allow if {
input.scope in {utils.DELETE, utils.UPDATE_ORG}
input.scope in {utils.DELETE, utils.UPDATE_ORG, utils.UPDATE_ASSOCIATED_STORAGE}
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.USER)
organizations.is_staff
Expand Down
24 changes: 19 additions & 5 deletions cvat/apps/engine/rules/tasks.rego
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import data.organizations

# input: {
# "scope": <"create"|"create@project"|"view"|"list"|"update:desc"|
# "update:owner"|"update:assignee"|"update:project"|"delete"|
# "view:annotations"|"update:annotations"|"delete:annotations"|
# "update:owner"|"update:assignee"|"update:project"|"update:associated_storage"|
# "delete"|"view:annotations"|"update:annotations"|"delete:annotations"|
# "export:dataset"|"view:data"|"upload:data"|"export:annotations"> or null,
# "auth": {
# "user": {
Expand Down Expand Up @@ -250,10 +250,17 @@ allow if {
utils.has_perm(utils.WORKER)
}

allow if {
input.scope == utils.UPDATE_ASSOCIATED_STORAGE
utils.is_sandbox
is_project_owner
utils.has_perm(utils.WORKER)
}

allow if {
input.scope in {
utils.UPDATE_OWNER, utils.UPDATE_ASSIGNEE, utils.UPDATE_PROJECT,
utils.DELETE, utils.UPDATE_ORG
utils.DELETE, utils.UPDATE_ORG, utils.UPDATE_ASSOCIATED_STORAGE
}
utils.is_sandbox
is_task_owner
Expand All @@ -263,7 +270,7 @@ allow if {
allow if {
input.scope in {
utils.UPDATE_OWNER, utils.UPDATE_ASSIGNEE, utils.UPDATE_PROJECT,
utils.DELETE, utils.UPDATE_ORG
utils.DELETE, utils.UPDATE_ORG, utils.UPDATE_ASSOCIATED_STORAGE
}
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.USER)
Expand All @@ -273,13 +280,20 @@ allow if {
allow if {
input.scope in {
utils.UPDATE_OWNER, utils.UPDATE_ASSIGNEE, utils.UPDATE_PROJECT,
utils.DELETE, utils.UPDATE_ORG
utils.DELETE, utils.UPDATE_ORG, utils.UPDATE_ASSOCIATED_STORAGE
}
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.WORKER)
organizations.has_perm(organizations.WORKER)
is_task_owner
}
allow if {
input.scope == utils.UPDATE_ASSOCIATED_STORAGE
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.WORKER)
organizations.has_perm(organizations.WORKER)
is_project_owner
}

allow if {
input.scope in {
Expand Down
7 changes: 6 additions & 1 deletion cvat/apps/engine/rules/tests/configs/projects.csv
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ export:backup,Project,Organization,None,,GET,/projects/{id}/backup,User,Maintain
update:organization,"Project, Organization",Sandbox,"None, Assignee",,PATCH,/projects/{id},Admin,N/A
update:organization,"Project, Organization",Sandbox,Owner,,PATCH,/projects/{id},Worker,N/A
update:organization,"Project, Organization",Organization,"None, Assignee",,PATCH,/projects/{id},User,Maintainer
update:organization,"Project, Organization",Organization,Owner,,PATCH,/projects/{id},Worker,Worker
update:organization,"Project, Organization",Organization,Owner,,PATCH,/projects/{id},Worker,Worker
update:associated_storage,Project,Sandbox,None,,PATCH,/projects/{id},Admin,N/A
update:associated_storage,Project,Sandbox,Owner,,PATCH,/projects/{id},Worker,N/A
update:associated_storage,Project,Organization,None,,PATCH,/projects/{id},Admin,N/A
update:associated_storage,Project,Organization,"None, Assignee",,PATCH,/projects/{id},User,Maintainer
update:associated_storage,Project,Organization,Owner,,PATCH,/projects/{id},Worker,Worker
5 changes: 5 additions & 0 deletions cvat/apps/engine/rules/tests/configs/tasks.csv
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ update:project,"Task, Project",Sandbox,"None, Assignee",,PATCH,/tasks/{id},Admin
update:project,"Task, Project",Sandbox,"Owner, Project:owner, Project:assignee",,PATCH,/tasks/{id},Worker,N/A
update:project,"Task, Project",Organization,"None, Assignee",,PATCH,/tasks/{id},User,Maintainer
update:project,"Task, Project",Organization,"Owner, Project:owner, Project:assignee",,PATCH,/tasks/{id},Worker,Worker
update:associated_storage,Task,Sandbox,None,,PATCH,/tasks/{id},Admin,N/A
update:associated_storage,Task,Sandbox,"Owner, Project:owner",,PATCH,/tasks/{id},Worker,N/A
update:associated_storage,Task,Organization,None,,PATCH,/tasks/{id},Admin,N/A
update:associated_storage,Task,Organization,"None, Assignee, Project:assignee",,PATCH,/tasks/{id},User,Maintainer
update:associated_storage,Task,Organization,"Owner, Project:owner",,PATCH,/tasks/{id},Worker,Worker
delete,Task,Sandbox,"None, Assignee",,DELETE,/tasks/{id},Admin,N/A
delete,Task,Sandbox,"Owner, Project:owner, Project:assignee",,DELETE,/tasks/{id},Worker,N/A
delete,Task,Organization,"None, Assignee",,DELETE,/tasks/{id},User,Maintainer
Expand Down
1 change: 1 addition & 0 deletions cvat/apps/iam/rules/utils.rego
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ RESEND := "resend"
UPDATE_DESC := "update:desc"
UPDATE_ASSIGNEE := "update:assignee"
UPDATE_OWNER := "update:owner"
UPDATE_ASSOCIATED_STORAGE := "update:associated_storage"
EXPORT_ANNOTATIONS := "export:annotations"
EXPORT_DATASET := "export:dataset"
CREATE_IN_PROJECT := "create@project"
Expand Down
7 changes: 4 additions & 3 deletions cvat/apps/organizations/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
#
# SPDX-License-Identifier: MIT

from typing import cast

from django.conf import settings

from cvat.apps.iam.permissions import OpenPolicyAgentPermission, StrEnum
Expand Down Expand Up @@ -175,7 +173,10 @@ def get_scopes(request, view, obj):
}[view.action]

if scope == Scopes.UPDATE:
if request.data.get('role') != cast(Membership, obj).role:
# user should have permissions to view a membership
scopes.append(Scopes.VIEW)

if 'role' in request.data.keys():
scopes.append(Scopes.UPDATE_ROLE)
else:
scopes.append(scope)
Expand Down
2 changes: 1 addition & 1 deletion cvat/schema.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: CVAT REST API
version: 2.19.0
version: 2.19.1
description: REST API for Computer Vision Annotation Tool (CVAT)
termsOfService: https://www.google.com/policies/terms/
contact:
Expand Down
18 changes: 9 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ services:

cvat_server:
container_name: cvat_server
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on:
<<: *backend-deps
Expand Down Expand Up @@ -112,7 +112,7 @@ services:

cvat_utils:
container_name: cvat_utils
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -129,7 +129,7 @@ services:

cvat_worker_import:
container_name: cvat_worker_import
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -145,7 +145,7 @@ services:

cvat_worker_export:
container_name: cvat_worker_export
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -161,7 +161,7 @@ services:

cvat_worker_annotation:
container_name: cvat_worker_annotation
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -177,7 +177,7 @@ services:

cvat_worker_webhooks:
container_name: cvat_worker_webhooks
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -193,7 +193,7 @@ services:

cvat_worker_quality_reports:
container_name: cvat_worker_quality_reports
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -209,7 +209,7 @@ services:

cvat_worker_analytics_reports:
container_name: cvat_worker_analytics_reports
image: cvat/server:${CVAT_VERSION:-v2.19.0}
image: cvat/server:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on: *backend-deps
environment:
Expand All @@ -225,7 +225,7 @@ services:

cvat_ui:
container_name: cvat_ui
image: cvat/ui:${CVAT_VERSION:-v2.19.0}
image: cvat/ui:${CVAT_VERSION:-v2.19.1}
restart: always
depends_on:
- cvat_server
Expand Down
4 changes: 2 additions & 2 deletions helm-chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ cvat:
additionalVolumeMounts: []
replicas: 1
image: cvat/server
tag: v2.19.0
tag: v2.19.1
imagePullPolicy: Always
permissionFix:
enabled: true
Expand All @@ -139,7 +139,7 @@ cvat:
frontend:
replicas: 1
image: cvat/ui
tag: v2.19.0
tag: v2.19.1
imagePullPolicy: Always
labels: {}
# test: test
Expand Down
Loading

0 comments on commit 4163cb2

Please sign in to comment.