Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apiserver/plane/app/views/asset/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def delete(self, request, workspace_id, asset_key):
asset_key = str(workspace_id) + "/" + asset_key
file_asset = FileAsset.objects.get(asset=asset_key)
file_asset.is_deleted = True
file_asset.save()
file_asset.save(update_fields=["is_deleted"])
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

Add permission checks and error handling.

While the update_fields optimization is good, this endpoint needs additional safeguards:

  1. Add permission checks to ensure the user has delete rights
  2. Add error handling for non-existent assets

Consider implementing these changes:

 def delete(self, request, workspace_id, asset_key):
     asset_key = str(workspace_id) + "/" + asset_key
-    file_asset = FileAsset.objects.get(asset=asset_key)
-    file_asset.is_deleted = True
-    file_asset.save(update_fields=["is_deleted"])
-    return Response(status=status.HTTP_204_NO_CONTENT)
+    try:
+        file_asset = FileAsset.objects.get(asset=asset_key)
+        
+        # Add permission check
+        if not request.user.has_workspace_permission(workspace_id, "delete"):
+            return Response(
+                {"error": "You don't have permission to delete this asset"},
+                status=status.HTTP_403_FORBIDDEN
+            )
+            
+        file_asset.is_deleted = True
+        file_asset.save(update_fields=["is_deleted"])
+        return Response(status=status.HTTP_204_NO_CONTENT)
+    except FileAsset.DoesNotExist:
+        return Response(
+            {"error": "Asset not found"},
+            status=status.HTTP_404_NOT_FOUND
+        )

Committable suggestion was skipped due to low confidence.

return Response(status=status.HTTP_204_NO_CONTENT)


Expand All @@ -59,7 +59,7 @@ def restore(self, request, workspace_id, asset_key):
asset_key = str(workspace_id) + "/" + asset_key
file_asset = FileAsset.objects.get(asset=asset_key)
file_asset.is_deleted = False
file_asset.save()
file_asset.save(update_fields=["is_deleted"])
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

Add permission checks and error handling for restore operation.

Similar to the delete endpoint, this restore operation needs additional safeguards.

Consider implementing these changes:

 def restore(self, request, workspace_id, asset_key):
     asset_key = str(workspace_id) + "/" + asset_key
-    file_asset = FileAsset.objects.get(asset=asset_key)
-    file_asset.is_deleted = False
-    file_asset.save(update_fields=["is_deleted"])
-    return Response(status=status.HTTP_204_NO_CONTENT)
+    try:
+        file_asset = FileAsset.objects.get(asset=asset_key)
+        
+        # Add permission check
+        if not request.user.has_workspace_permission(workspace_id, "update"):
+            return Response(
+                {"error": "You don't have permission to restore this asset"},
+                status=status.HTTP_403_FORBIDDEN
+            )
+            
+        file_asset.is_deleted = False
+        file_asset.save(update_fields=["is_deleted"])
+        return Response(status=status.HTTP_204_NO_CONTENT)
+    except FileAsset.DoesNotExist:
+        return Response(
+            {"error": "Asset not found"},
+            status=status.HTTP_404_NOT_FOUND
+        )
📝 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
file_asset.save(update_fields=["is_deleted"])
def restore(self, request, workspace_id, asset_key):
asset_key = str(workspace_id) + "/" + asset_key
try:
file_asset = FileAsset.objects.get(asset=asset_key)
# Add permission check
if not request.user.has_workspace_permission(workspace_id, "update"):
return Response(
{"error": "You don't have permission to restore this asset"},
status=status.HTTP_403_FORBIDDEN
)
file_asset.is_deleted = False
file_asset.save(update_fields=["is_deleted"])
return Response(status=status.HTTP_204_NO_CONTENT)
except FileAsset.DoesNotExist:
return Response(
{"error": "Asset not found"},
status=status.HTTP_404_NOT_FOUND
)

return Response(status=status.HTTP_204_NO_CONTENT)


Expand Down Expand Up @@ -96,5 +96,5 @@ def delete(self, request, asset_key):
asset=asset_key, created_by=request.user
)
file_asset.is_deleted = True
file_asset.save()
file_asset.save(update_fields=["is_deleted"])
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

Add error handling for the delete operation.

While this endpoint correctly scopes to user's own assets, it still needs error handling.

Consider implementing these changes:

 def delete(self, request, asset_key):
-    file_asset = FileAsset.objects.get(
-        asset=asset_key, created_by=request.user
-    )
-    file_asset.is_deleted = True
-    file_asset.save(update_fields=["is_deleted"])
-    return Response(status=status.HTTP_204_NO_CONTENT)
+    try:
+        file_asset = FileAsset.objects.get(
+            asset=asset_key, created_by=request.user
+        )
+        file_asset.is_deleted = True
+        file_asset.save(update_fields=["is_deleted"])
+        return Response(status=status.HTTP_204_NO_CONTENT)
+    except FileAsset.DoesNotExist:
+        return Response(
+            {"error": "Asset not found"},
+            status=status.HTTP_404_NOT_FOUND
+        )

Committable suggestion was skipped due to low confidence.

return Response(status=status.HTTP_204_NO_CONTENT)
21 changes: 9 additions & 12 deletions apiserver/plane/app/views/asset/v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def asset_delete(self, asset_id):
return
asset.is_deleted = True
asset.deleted_at = timezone.now()
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return

def entity_asset_save(self, asset_id, entity_type, asset, request):
Expand Down Expand Up @@ -209,8 +209,7 @@ def patch(self, request, asset_id):
# update the attributes
asset.attributes = request.data.get("attributes", asset.attributes)
# save the asset
asset.created_by = request.user
asset.save()
asset.save(update_fields=["is_uploaded", "attributes"])
return Response(status=status.HTTP_204_NO_CONTENT)

def delete(self, request, asset_id):
Expand All @@ -221,7 +220,7 @@ def delete(self, request, asset_id):
self.entity_asset_delete(
entity_type=asset.entity_type, asset=asset, request=request
)
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return Response(status=status.HTTP_204_NO_CONTENT)


Expand Down Expand Up @@ -280,7 +279,7 @@ def asset_delete(self, asset_id):
# Mark the asset as deleted
asset.is_deleted = True
asset.deleted_at = timezone.now()
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return

def entity_asset_save(self, asset_id, entity_type, asset, request):
Expand Down Expand Up @@ -460,8 +459,7 @@ def patch(self, request, slug, asset_id):
# update the attributes
asset.attributes = request.data.get("attributes", asset.attributes)
# save the asset
asset.created_by = request.user
asset.save()
asset.save(update_fields=["is_uploaded", "attributes"])
return Response(status=status.HTTP_204_NO_CONTENT)

def delete(self, request, slug, asset_id):
Expand All @@ -472,7 +470,7 @@ def delete(self, request, slug, asset_id):
self.entity_asset_delete(
entity_type=asset.entity_type, asset=asset, request=request
)
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return Response(status=status.HTTP_204_NO_CONTENT)

def get(self, request, slug, asset_id):
Expand Down Expand Up @@ -551,7 +549,7 @@ def post(self, request, slug, asset_id):
asset = FileAsset.all_objects.get(id=asset_id, workspace__slug=slug)
asset.is_deleted = False
asset.deleted_at = None
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return Response(status=status.HTTP_204_NO_CONTENT)


Expand Down Expand Up @@ -692,8 +690,7 @@ def patch(self, request, slug, project_id, pk):
# update the attributes
asset.attributes = request.data.get("attributes", asset.attributes)
# save the asset
asset.created_by = request.user
asset.save()
asset.save(update_fields=["is_uploaded", "attributes"])
return Response(status=status.HTTP_204_NO_CONTENT)

@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
Expand All @@ -708,7 +705,7 @@ def delete(self, request, slug, project_id, pk):
asset.is_deleted = True
asset.deleted_at = timezone.now()
# Save the asset
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return Response(status=status.HTTP_204_NO_CONTENT)

@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
Expand Down
2 changes: 1 addition & 1 deletion apiserver/plane/bgtasks/storage_metadata_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def get_asset_object_metadata(asset_id):
object_name=asset.asset.name
)
# Save the asset
asset.save()
asset.save(update_fields=["storage_metadata"])
return
except FileAsset.DoesNotExist:
return
Expand Down
7 changes: 3 additions & 4 deletions apiserver/plane/space/views/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,7 @@ def patch(self, request, anchor, pk):
# update the attributes
asset.attributes = request.data.get("attributes", asset.attributes)
# save the asset
asset.created_by = request.user
asset.save()
asset.save(update_fields=["attributes", "is_uploaded"])
return Response(status=status.HTTP_204_NO_CONTENT)

def delete(self, request, anchor, pk):
Expand All @@ -194,7 +193,7 @@ def delete(self, request, anchor, pk):
asset.is_deleted = True
asset.deleted_at = timezone.now()
# Save the asset
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return Response(status=status.HTTP_204_NO_CONTENT)


Expand All @@ -219,7 +218,7 @@ def post(self, request, anchor, asset_id):
)
asset.is_deleted = False
asset.deleted_at = None
asset.save()
asset.save(update_fields=["is_deleted", "deleted_at"])
return Response(status=status.HTTP_204_NO_CONTENT)


Expand Down