Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow quality reports to regular users #8511

Merged
merged 19 commits into from
Oct 10, 2024

Conversation

zhiltsov-max
Copy link
Contributor

@zhiltsov-max zhiltsov-max commented Oct 4, 2024

Motivation and context

  • Allowed quality report computation for tasks to regular users (before this only admins could trigger custom report computations)
  • Refactored quality control tests

How has this been tested?

Unit tests

Checklist

  • I submit my changes into the develop branch
  • I have created a changelog fragment
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • I have linked related issues (see GitHub docs)
  • I have increased versions of npm packages if it is necessary
    (cvat-canvas,
    cvat-core,
    cvat-data and
    cvat-ui)

License

  • I submit my code changes under the same MIT License that covers the project.
    Feel free to contact the maintainers if that's a concern.

Summary by CodeRabbit

Release Notes

  • New Features

    • Regular users can now generate quality reports, expanding access to this functionality.
    • New API endpoints for managing cloud storages, webhooks, and quality reports have been introduced.
  • Improvements

    • Enhanced permission handling for quality reports, including task-specific checks.
    • Improved job scheduling and reporting mechanisms for quality check jobs.
  • Bug Fixes

    • Adjusted logic for user permissions related to tasks and projects, ensuring accurate access control.
  • Tests

    • Added new tests to verify the creation of quality reports by users in different task contexts.

Copy link
Contributor

coderabbitai bot commented Oct 4, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes in this pull request enhance the quality report generation capabilities of the application by allowing regular users to compute quality reports, previously restricted to certain roles. Modifications include the introduction of new constants and predicates for permissions, updates to the QualityReportPermission class to handle task-related permissions, and enhancements to job scheduling and reporting mechanisms. Additionally, the OpenAPI schema has been updated to reflect new and modified endpoints, and new tests have been added to ensure proper functionality.

Changes

File Change Summary
changelog.d/20241004_201336_mzhiltso_allow_quality_reports_for_regular_users.md Updated to allow regular users to compute quality reports.
cvat/apps/iam/rules/utils.rego Added constant VIEW_STATUS := "view:status" to the utils package.
cvat/apps/quality_control/permissions.py Added optional attribute task_id to QualityReportPermission. Updated create_scope_check_status method to use VIEW_STATUS. Enhanced create and get_resource methods for task handling.
cvat/apps/quality_control/quality_reports.py Updated QualityReportUpdateManager with new job ID prefixes and return type annotations. Introduced JobAlreadyExists exception for job scheduling. Enhanced methods for job handling and report computation.
cvat/apps/quality_control/rules/conflicts.rego Added predicates for user roles related to tasks and projects, enhancing permission logic.
cvat/apps/quality_control/rules/quality_reports.rego Introduced new predicates for user roles and modified allow rule logic for task and project access.
cvat/apps/quality_control/serializers.py Updated task_id field in QualityReportCreateSerializer to be optional.
cvat/apps/quality_control/views.py Renamed method schedule_quality_check_job to schedule_custom_quality_check_job and updated parameter handling in create method.
cvat/schema.yml Comprehensive update to OpenAPI specification, including new endpoints for quality reports, cloud storages, and webhooks.
tests/python/rest_api/test_quality_control.py Added new tests for creating quality reports, verifying user permissions and roles.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant API
    participant QualityReportManager
    participant QualityReportPermission

    User->>API: Request to create quality report
    API->>QualityReportPermission: Check permissions
    QualityReportPermission-->>API: Permissions valid
    API->>QualityReportManager: Schedule quality check job
    QualityReportManager-->>API: Job scheduled
    API-->>User: Quality report creation success
Loading

🐇 "In the fields where bunnies hop,
Quality reports now never stop.
With tasks and roles, we play our part,
New features bloom, a work of art!
So let us cheer, with joy we sing,
For every change, a happy spring!" 🐰✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🧹 Outside diff range and nitpick comments (9)
changelog.d/20241004_201336_mzhiltso_allow_quality_reports_for_regular_users.md (1)

1-4: LGTM! Consider adding a brief impact statement.

The changelog entry accurately reflects the PR objectives and follows a good format. It correctly identifies the change as allowing regular users to compute quality reports via the Server API.

To provide more context, consider adding a brief statement about the impact or benefit of this change. For example:

 ### Changed

 - [Server API] Quality report computation is now allowed to regular users
+  (improves accessibility and empowers users to generate custom reports)
   (https://github.com/cvat-ai/cvat/pull/8511)

This addition would help readers quickly understand the significance of the change.

cvat/apps/quality_control/serializers.py (1)

No existing tests found for quality report serializers

It appears that there are no test files related to quality reports or serializers. To ensure the reliability of the QualityReportCreateSerializer and related components:

  • Create unit tests for QualityReportCreateSerializer covering scenarios where task_id is provided and omitted.
  • Develop integration tests to verify the end-to-end creation of quality reports, ensuring proper interaction with other serializers and system components.
🔗 Analysis chain

Line range hint 1-70: Ensure comprehensive testing of the quality report creation process

While the change is isolated to the QualityReportCreateSerializer, it may have implications for how other parts of the system interact with it. To ensure the robustness of this change:

  1. Update existing unit tests to cover scenarios where task_id is not provided.
  2. Add integration tests to verify the end-to-end process of creating quality reports for both admin and regular users.
  3. Test the interaction between QualityReportCreateSerializer and other serializers in this file, especially QualityReportSerializer and QualitySettingsSerializer.

To help with testing, you can use the following script to identify relevant test files:

This will help you locate the appropriate test files to update or add new tests.

Also applies to: 71-184

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find relevant test files for quality report functionality

echo "Test files related to quality reports:"
fd -e py test.*quality.*report

echo "\nTest files related to serializers:"
fd -e py test.*serializer

Length of output: 340


Script:

#!/bin/bash
# Description: Find relevant test files for quality report functionality using fd

echo "Test files related to quality reports:"
fd -e py -i 'test.*quality.*report' .

echo "\nTest files related to serializers:"
fd -e py -i 'test.*serializer' .

Length of output: 244

tests/python/rest_api/test_quality_control.py (3)

587-609: LGTM: Well-structured parameterized test with a minor suggestion.

The test_user_create_report_in_sandbox_task method is a well-implemented parameterized test that covers both allowed and forbidden scenarios for creating quality reports in sandbox tasks. It effectively uses helper methods to improve readability and maintainability.

Consider extracting the task selection logic into a separate helper method to improve readability. For example:

def _get_sandbox_task(tasks, jobs, users):
    return next(
        t
        for t in tasks
        if t["organization"] is None
        and not users[t["owner"]["id"]]["is_superuser"]
        and not any(j for j in jobs if j["task_id"] == t["id"] and j["type"] == "ground_truth")
    )

This would simplify the main test method and make it easier to understand at a glance.


611-663: LGTM: Comprehensive parameterized test with suggestions for improvement.

The test_user_create_report_in_org_task method is a well-structured parameterized test that covers various scenarios for creating quality reports in organization tasks. It effectively uses helper methods and parameterization to test different user roles and permissions.

Consider the following improvements to enhance readability and maintainability:

  1. Extract the task selection logic into a separate helper method:
def _get_org_task(tasks, jobs, users, is_org_member, is_task_staff, org_role, is_staff):
    for user in users:
        if user["is_superuser"]:
            continue
        task = next(
            (
                t
                for t in tasks
                if t["organization"] is not None
                and is_task_staff(user["id"], t["id"]) == is_staff
                and is_org_member(user["id"], t["organization"], role=org_role)
                and not any(
                    j for j in jobs if j["task_id"] == t["id"] and j["type"] == "ground_truth"
                )
            ),
            None,
        )
        if task is not None:
            return user, task
    return None, None
  1. Simplify the main test method using the extracted helper:
def test_user_create_report_in_org_task(
    self,
    tasks,
    jobs,
    users,
    is_org_member,
    is_task_staff,
    org_role,
    is_staff,
    allow,
    admin_user,
):
    user, task = self._get_org_task(tasks, jobs, users, is_org_member, is_task_staff, org_role, is_staff)
    assert task is not None, "No suitable task found for the test"

    self.create_gt_job(admin_user, task["id"])

    if allow:
        self._test_create_report_200(user["username"], task["id"])
    else:
        self._test_create_report_403(user["username"], task["id"])

These changes will improve the readability of the test method and make it easier to maintain and update in the future.


573-663: Overall assessment: Well-structured tests with room for minor improvements.

The new changes introduce well-designed test methods for quality report creation in various scenarios. The use of helper methods and parameterized tests enhances the overall test coverage and maintainability. While the implementation is generally sound, there are opportunities to improve readability and organization, particularly in the task selection logic for both sandbox and organization tasks.

Consider implementing the suggested improvements for extracting complex logic into helper methods. This will make the tests more readable and easier to maintain in the long run. Additionally, ensure consistent naming conventions and documentation for all test methods to further enhance the overall quality of the test suite.

cvat/apps/quality_control/rules/quality_reports.rego (1)

Line range hint 155-169: Optimize filter conditions to reduce redundancy

The filter conditions contain multiple repetitive checks for organization IDs and user IDs. Consider consolidating these conditions or using helper predicates to simplify the logic and enhance readability.

cvat/apps/quality_control/quality_reports.py (3)

13-13: Remove unused import sleep

The sleep function from the time module is imported but not used in the code. Unused imports can clutter the codebase and should be removed to improve maintainability.

Apply this diff to remove the unused import:

-from time import sleep

2231-2231: Replace print statement with proper logging

Using print statements is not recommended for production code. It's better to use the logging module to log information, which provides more flexibility and control over log levels and outputs.

Apply this diff to use logging instead:

+import logging
...
-def get_quality_check_job(self, ...):
+    logger = logging.getLogger(__name__)
...
-    print(queue.fetch_job(rq_id).get_status())
+    logger.info(f"Job {rq_id} status: {queue.fetch_job(rq_id).get_status()}")

Ensure that import logging is at the top of the file.


2208-2230: Review lock mechanism and exception handling in job scheduling

The use of get_rq_lock_by_user ensures that only one job per user is scheduled at a time. However, it's important to ensure that this lock mechanism doesn't introduce deadlocks or block other important operations.

Consider reviewing and testing the locking mechanism under high concurrency to ensure it behaves as expected. Additionally, ensure that exceptions within the locked block are properly handled to release the lock and avoid blocking subsequent operations.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1285858 and 2311992.

📒 Files selected for processing (10)
  • changelog.d/20241004_201336_mzhiltso_allow_quality_reports_for_regular_users.md (1 hunks)
  • cvat/apps/iam/rules/utils.rego (1 hunks)
  • cvat/apps/quality_control/permissions.py (5 hunks)
  • cvat/apps/quality_control/quality_reports.py (5 hunks)
  • cvat/apps/quality_control/rules/conflicts.rego (3 hunks)
  • cvat/apps/quality_control/rules/quality_reports.rego (4 hunks)
  • cvat/apps/quality_control/serializers.py (1 hunks)
  • cvat/apps/quality_control/views.py (2 hunks)
  • cvat/schema.yml (0 hunks)
  • tests/python/rest_api/test_quality_control.py (1 hunks)
💤 Files with no reviewable changes (1)
  • cvat/schema.yml
🧰 Additional context used
🪛 GitHub Check: CodeQL
cvat/apps/quality_control/permissions.py

[warning] 74-74: Information exposure through an exception
Stack trace information flows to this location and may be exposed to an external user.

🔇 Additional comments (13)
cvat/apps/iam/rules/utils.rego (1)

61-61: New constant VIEW_STATUS added

The addition of VIEW_STATUS := "view:status" constant is consistent with the existing naming conventions for permission scopes in this file. This new constant likely represents a new permission for viewing status information, which aligns with the PR objective of allowing regular users to compute quality reports.

However, there are a few points to consider:

  1. The PR objectives mention allowing users to "compute" quality reports, but the constant only implies "viewing" status. It's unclear if this fully addresses the requirement.
  2. There are no accompanying changes to implement the usage of this new constant.

To ensure this change is properly implemented and used, let's check for its usage:

✅ Verification successful

Verified Usage of VIEW_STATUS Constant

The VIEW_STATUS constant defined in cvat/apps/iam/rules/utils.rego is utilized in cvat/apps/quality_control/rules/quality_reports.rego as input.scope == utils.VIEW_STATUS. This usage aligns with the PR objective of allowing regular users to compute quality reports for tasks by defining the necessary permission scope.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of the new VIEW_STATUS constant
rg --type rego "VIEW_STATUS"

# Search for any new rules or changes related to quality reports or status viewing
rg --type rego -i "quality report|view status"

Length of output: 135


Script:

#!/bin/bash
# Search for usage of the new VIEW_STATUS constant in .rego files
rg "VIEW_STATUS" --glob "*.rego"

# Search for any new rules or changes related to quality reports or status viewing in .rego files
rg -i "quality report|view status" --glob "*.rego"

Length of output: 235

cvat/apps/quality_control/serializers.py (1)

70-70: LGTM! Consider adding explanatory comment and verify impact.

The change to make task_id optional aligns with the PR objective of allowing regular users to compute quality reports for tasks. This is a good modification.

However, I have a few suggestions:

  1. Add a comment explaining why this field is now optional. This will help future developers understand the reasoning behind this change.

  2. Verify that this change doesn't break existing functionality for admin users.

  3. Check if additional validation logic is needed elsewhere in the codebase to handle cases where task_id is not provided.

To verify the impact of this change, you can run the following script:

#!/bin/bash
# Description: Check for usages of QualityReportCreateSerializer and potential places that might need additional validation

# Search for usages of QualityReportCreateSerializer
echo "Usages of QualityReportCreateSerializer:"
rg "QualityReportCreateSerializer" --type python

# Search for potential validation points related to task_id in views
echo "\nPotential validation points for task_id:"
rg "task_id.*request\.data" --type python

This script will help identify areas of the codebase that might be affected by this change and where additional validation might be needed.

tests/python/rest_api/test_quality_control.py (2)

573-574: LGTM: Well-structured helper method.

The _test_create_report_200 method is a concise and well-named helper function for testing the successful creation of a quality report. It follows good practices for test helper methods.


576-585: LGTM: Well-implemented error case helper method.

The _test_create_report_403 method is a well-structured helper function for testing the forbidden access scenario when creating a quality report. It uses appropriate context management for the API client and correctly asserts the expected HTTP status code.

cvat/apps/quality_control/rules/quality_reports.rego (1)

103-107: Verify permission levels for creating and viewing in sandbox environment

In the rule:

allow if {
    input.scope in {utils.CREATE, utils.VIEW}
    utils.is_sandbox
    is_task_staff
    utils.has_perm(utils.WORKER)
}

Ensure that assigning the utils.WORKER permission is appropriate for regular users in the sandbox environment who need to create or view quality reports. Adjust the permission level if necessary to match the intended access control.

cvat/apps/quality_control/rules/conflicts.rego (2)

7-7: Verify the necessity of importing data.tasks.

The import statement import data.tasks was added. Please confirm that data.tasks is actually used within this policy. If it's unused, consider removing it to keep the code clean and avoid unnecessary dependencies.


97-102: Review access control conditions for VIEW scope in sandbox environment.

In this allow rule, access is granted if the user is is_task_staff and has the utils.has_perm(utils.WORKER) permission. Verify that regular users who are task staff have the WORKER permission, or adjust the permission check accordingly to match the intended access control.

cvat/apps/quality_control/permissions.py (3)

21-21: Addition of task_id attribute enhances permission handling

The introduction of task_id: Optional[int] in the QualityReportPermission class allows for more granular permission checks related to specific tasks.


33-33: Consistent use of VIEW_STATUS scope improves maintainability

Using cls.Scopes.VIEW_STATUS instead of a string literal enhances code consistency and reduces the risk of typos.


Line range hint 139-154: Verify handling of potential None values in resource data

When constructing the data dictionary, attributes like task, task.owner, task.assignee, task.project, and their respective owners and assignees may be None. Ensure that the code accounts for these possibilities to prevent AttributeError.

cvat/apps/quality_control/views.py (1)

275-276: Ensure 'schedule_custom_quality_check_job' is correctly implemented

The method call has been updated to schedule_custom_quality_check_job with the additional request parameter. Verify that this method is defined in QualityReportUpdateManager and correctly handles the request, task, and user_id parameters.

To confirm the method's existence and signature, you can run the following script:

✅ Verification successful

'schedule_custom_quality_check_job' is correctly implemented

  • The method schedule_custom_quality_check_job is defined in QualityReportUpdateManager within cvat/apps/quality_control/quality_reports.py with the parameters request, task, and user_id as required.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that 'schedule_custom_quality_check_job' is defined with the correct parameters.

# Test: Search for the method definition.
rg --type python -A 5 $'def schedule_custom_quality_check_job(request, task, user_id)' --path 'cvat/apps/quality_control/'

Length of output: 556


Script:

#!/bin/bash
# Description: Verify that 'schedule_custom_quality_check_job' is defined with the correct parameters.

# Corrected Test: Search for the method definition without using the invalid '--path' flag.
rg --type python -A 5 'def schedule_custom_quality_check_job\(request, task, user_id\)' cvat/apps/quality_control/

Length of output: 147


Script:

#!/bin/bash
# Description: Verify that 'schedule_custom_quality_check_job' is defined with the correct parameters.

# Corrected Test: Use the correct type identifier 'py' instead of 'python'.
rg --type py -A 5 'def schedule_custom_quality_check_job\(request, task, user_id\)' cvat/apps/quality_control/

Length of output: 112


Script:

#!/bin/bash
# Description: Broadly search for the definition of 'schedule_custom_quality_check_job' without file type restrictions.

# Broad Search: Look for any definition of the method, regardless of file type.
rg 'def schedule_custom_quality_check_job' cvat/apps/quality_control/

Length of output: 210

cvat/apps/quality_control/quality_reports.py (2)

26-28: Verify necessity of newly added imports

The imports for RqQueue, RqJob, and RqScheduler have been added. Ensure that these classes are used in the code. Unused imports can be removed to keep the code clean.

Run the following script to check for their usage:

✅ Verification successful

Imports are used and necessary

The imports for RqQueue, RqJob, and RqScheduler are utilized in quality_reports.py as follows:

  • RqScheduler in the _get_scheduler method.
  • RqQueue in the _get_queue method.
  • RqJob in the get_quality_check_job and is_custom_quality_check_job methods.

These imports are necessary and should be retained.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of RqQueue, RqJob, and RqScheduler

# Test: Search for usage of these classes in the codebase
rg --type py '\b(RqQueue|RqJob|RqScheduler)\b' cvat/apps/quality_control/ -A 2

# Expected result: Instances where these classes are used should be found.

Length of output: 1588


55-55: Verify usage of newly imported utility functions

The functions define_dependent_job, get_rq_job_meta, and get_rq_lock_by_user are imported. Ensure that these functions are actually used in the codebase. Unused imports should be removed to keep the code clean.

Run the following script to check for their usage:

✅ Verification successful

Imported utility functions are utilized appropriately

The imported functions define_dependent_job, get_rq_job_meta, and get_rq_lock_by_user are used within quality_reports.py. No unused imports detected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of imported utility functions

# Test: Search for usage of the functions in the codebase
rg --type py '\b(define_dependent_job|get_rq_job_meta|get_rq_lock_by_user)\b' cvat/apps/quality_control/ -A 2

# Expected result: Instances where these functions are used should be found.

Length of output: 1344

@@ -58,6 +58,7 @@ IMPORT_DATASET := "import:dataset"
IMPORT_BACKUP := "import:backup"
EXPORT_BACKUP := "export:backup"
UPDATE_ORG := "update:organization"
VIEW_STATUS := "view:status"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incomplete implementation of PR objectives

While the addition of the VIEW_STATUS constant is a step in the right direction, it appears that the implementation is incomplete based on the PR objectives. The PR aims to "allow regular users to compute quality reports for tasks," but the current changes only add a constant for viewing status.

To fully implement the desired functionality, consider the following:

  1. Add rules or functions that use the new VIEW_STATUS constant to grant permissions to regular users.
  2. Implement the actual computation of quality reports, which may involve changes in other files.
  3. Ensure that the permission check is integrated into the quality report computation process.

Would you like assistance in drafting the additional rules or functions needed to complete this implementation?

cvat/apps/quality_control/rules/quality_reports.rego Outdated Show resolved Hide resolved
cvat/apps/quality_control/rules/quality_reports.rego Outdated Show resolved Hide resolved
cvat/apps/quality_control/rules/quality_reports.rego Outdated Show resolved Hide resolved
cvat/apps/quality_control/rules/quality_reports.rego Outdated Show resolved Hide resolved
cvat/apps/quality_control/permissions.py Outdated Show resolved Hide resolved
@@ -290,7 +290,7 @@ def create(self, request, *args, **kwargs):
if (
not rq_job
or not QualityReportPermission.create_scope_check_status(
request, job_owner_id=rq_job.meta["user_id"]
request, job_owner_id=rq_job.meta["user"]["id"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential KeyError when accessing 'rq_job.meta["user"]["id"]'

Accessing rq_job.meta["user"]["id"] assumes that the meta dictionary always contains the user key with an id. If either key is missing, a KeyError will be raised, leading to an unhandled exception. Consider adding error handling to manage this possibility.

Apply this diff to safely access the nested id key:

-                     request, job_owner_id=rq_job.meta["user"]["id"]
+                     try:
+                         user_id = rq_job.meta["user"]["id"]
+                     except KeyError:
+                         raise ValidationError("User ID not found in job metadata")
+                     request, job_owner_id=user_id
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
request, job_owner_id=rq_job.meta["user"]["id"]
try:
user_id = rq_job.meta["user"]["id"]
except KeyError:
raise ValidationError("User ID not found in job metadata")
request, job_owner_id=user_id

Comment on lines 2210 to 2216
rq_job = queue.fetch_job(rq_id)
if rq_job and rq_job.get_status(refresh=False) in (
rq.job.JobStatus.QUEUED,
rq.job.JobStatus.STARTED,
rq.job.JobStatus.SCHEDULED,
):
raise self.JobAlreadyExists()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential exceptions when fetching job status

Fetching the job status may raise exceptions if the job does not exist or if there's a connection issue with the queue. It's important to handle these exceptions to prevent crashes and provide meaningful error messages.

Consider adding exception handling around the job fetching and status checking:

try:
    rq_job = queue.fetch_job(rq_id)
    if rq_job and rq_job.get_status(refresh=False) in (
        rq.job.JobStatus.QUEUED,
        rq.job.JobStatus.STARTED,
        rq.job.JobStatus.SCHEDULED,
    ):
        raise self.JobAlreadyExists()
except Exception as e:
    logger.error(f"Failed to fetch job status for {rq_id}: {e}")
    # Handle the exception as appropriate

cvat/apps/quality_control/quality_reports.py Show resolved Hide resolved
Comment on lines +2195 to +2197
class JobAlreadyExists(QualityReportsNotAvailable):
def __str__(self):
return "Quality computation job for this task already enqueued"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Adjust inheritance of JobAlreadyExists exception

The JobAlreadyExists exception currently inherits from QualityReportsNotAvailable, which might not be semantically appropriate. Since JobAlreadyExists represents a different kind of error (a job is already enqueued), it would be clearer to inherit from a more general exception class like Exception or define a new base exception class for job scheduling errors.

Apply this diff to adjust the inheritance:

-class JobAlreadyExists(QualityReportsNotAvailable):
+class JobAlreadyExists(Exception):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class JobAlreadyExists(QualityReportsNotAvailable):
def __str__(self):
return "Quality computation job for this task already enqueued"
class JobAlreadyExists(Exception):
def __str__(self):
return "Quality computation job for this task already enqueued"

@codecov-commenter
Copy link

codecov-commenter commented Oct 4, 2024

Codecov Report

Attention: Patch coverage is 31.94444% with 49 lines in your changes missing coverage. Please review.

Project coverage is 74.28%. Comparing base (5f27977) to head (13ce04b).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8511      +/-   ##
===========================================
- Coverage    74.33%   74.28%   -0.05%     
===========================================
  Files          397      397              
  Lines        43139    43181      +42     
  Branches      3905     3905              
===========================================
+ Hits         32066    32077      +11     
- Misses       11073    11104      +31     
Components Coverage Δ
cvat-ui 78.68% <ø> (ø)
cvat-server 70.54% <31.94%> (-0.09%) ⬇️


is_task_owner(task_data, auth_data) if {
task_data.owner.id == auth_data.user.id
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to move to engine at some point

@Marishka17 Marishka17 self-assigned this Oct 8, 2024
Comment on lines 61 to 82
allow if {
input.scope == utils.VIEW
utils.is_sandbox
quality_utils.is_task_staff(input.resource.task, input.resource.project, input.auth)
utils.has_perm(utils.WORKER)
}

allow if {
input.scope == utils.VIEW
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.USER)
organizations.has_perm(organizations.MAINTAINER)
}

allow if {
input.scope == utils.VIEW
quality_utils.is_task_staff(input.resource.task, input.resource.project, input.auth)
input.auth.organization.id == input.resource.organization.id
utils.has_perm(utils.WORKER)
organizations.has_perm(organizations.WORKER)
}

Copy link
Contributor

@Marishka17 Marishka17 Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhiltsov-max, I've not found any place where these rules are used. Could you let me know why you added them? Are you going to introduce the GET /api/quality/conflicts/<id> endpoint? 👀

@Marishka17 Marishka17 force-pushed the zm/allow-quality-reports-for-regular-users branch from d18480d to 678cae5 Compare October 8, 2024 15:24
Copy link
Contributor

@Marishka17 Marishka17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I've not changed permission rules used when checking the status of an rq job in this PR because right now a new rq job to perform quality report computation will be created for each user that has access to a task (because the rq id template includes user_id). In this case, it seems logical to allow only the rq job owner to check the report creation progress.
However, I don't think it's a desirable approach to allow different users to compute quality reports for the same task at the same moment. I've not changed it in this PR because I cannot figure out why Maxim decided so. I suggest waiting for Maxim's response and fixing it in the next PR.

@Marishka17 Marishka17 force-pushed the zm/allow-quality-reports-for-regular-users branch from bfe1488 to 13ce04b Compare October 9, 2024 11:09
Copy link

sonarcloud bot commented Oct 9, 2024

@Marishka17 Marishka17 merged commit d315d78 into develop Oct 10, 2024
34 checks passed
@cvat-bot cvat-bot bot mentioned this pull request Oct 10, 2024
@bsekachev bsekachev deleted the zm/allow-quality-reports-for-regular-users branch October 24, 2024 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants