Skip to content

Commit da0ff94

Browse files
committed
Protect against allocation deletions
1 parent 9c4cfc5 commit da0ff94

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

coral_credits/api/db_exceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ class NoResourceClass(Exception):
2020
"""Raised when there is no resource class matching the query"""
2121

2222
pass
23+
24+
class ActiveConsumersInAllocation(Exception):
25+
"""Raised when trying to delete an allocation with active consumers"""
26+
27+
pass

coral_credits/api/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ def __str__(self) -> str:
101101
class Consumer(models.Model):
102102
consumer_ref = models.CharField(max_length=200)
103103
consumer_uuid = models.UUIDField()
104+
# Should protect against deletion with on_delete=models.DO_NOTHING but means can't
105+
# delete accounts with expired consumers so protected against in API instead
104106
resource_provider_account = models.ForeignKey(
105-
ResourceProviderAccount, on_delete=models.DO_NOTHING
107+
ResourceProviderAccount, on_delete=models.CASCADE
106108
)
107109
user_ref = models.UUIDField()
108110
created = models.DateTimeField(auto_now_add=True)

coral_credits/api/views.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ class CreditAllocationViewSet(viewsets.ModelViewSet):
2121
serializer_class = serializers.CreditAllocationSerializer
2222
permission_classes = [permissions.IsAuthenticated]
2323

24+
def destroy(self, request, pk=None):
25+
allocation = get_object_or_404(self.queryset, pk=pk)
26+
active_consumers = models.Consumer.objects.filter(
27+
resource_provider_account__account__pk=allocation.account.pk
28+
)
29+
current_time = make_aware(datetime.now())
30+
for consumer in active_consumers:
31+
if current_time < consumer.end:
32+
return _http_403_forbidden(repr(db_exceptions.ActiveConsumersInAllocation))
33+
else:
34+
return super().destroy(request)
35+
2436

2537
class CreditAllocationResourceViewSet(viewsets.ModelViewSet):
2638
serializer_class = serializers.CreditAllocationResourceSerializer

0 commit comments

Comments
 (0)