Skip to content

Commit

Permalink
Fix: Do not allow multiple deletion request against the same instance
Browse files Browse the repository at this point in the history
  • Loading branch information
Sispheor committed May 16, 2024
1 parent 729fafb commit 47cf264
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 12 deletions.
5 changes: 5 additions & 0 deletions service_catalog/models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from Squest.utils.ansible_when import AnsibleWhen
from Squest.utils.squest_model import SquestModel
from profiles.models.scope import Scope
from service_catalog.models import RequestState, OperationType
from service_catalog.models.hooks import HookManager
from service_catalog.models.instance_state import InstanceState
from service_catalog.models.services import Service
Expand Down Expand Up @@ -210,6 +211,10 @@ def on_change(cls, sender, instance, *args, **kwargs):
HookManager.trigger_hook(sender=sender, instance=instance, name="on_change_instance", source=previous.state, target=instance.state,
*args, **kwargs)

@property
def has_pending_delete_request(self):
return self.request_set.filter(state__in=[RequestState.SUBMITTED, RequestState.ACCEPTED],
operation__type=OperationType.DELETE).exists()


pre_save.connect(Instance.on_change, sender=Instance)
Expand Down
9 changes: 6 additions & 3 deletions service_catalog/views/instance.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
Expand All @@ -6,9 +8,9 @@
from django.urls import reverse
from django.utils.safestring import mark_safe
from django_fsm import can_proceed
from Squest.utils.squest_table import SquestRequestConfig
from jinja2 import UndefinedError, TemplateError

from Squest.utils.squest_table import SquestRequestConfig
from Squest.utils.squest_views import SquestListView, SquestDetailView, SquestUpdateView, SquestDeleteView, \
SquestPermissionDenied
from service_catalog.filters.instance_filter import InstanceFilter, InstanceArchivedFilter
Expand All @@ -25,8 +27,6 @@
from service_catalog.tables.request_tables import RequestTable
from service_catalog.tables.support_tables import SupportTable

import logging

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -172,6 +172,9 @@ def instance_request_new_operation(request, instance_id, operation_id):
raise PermissionDenied("Operation service and instance service doesn't match")
if operation.type not in [OperationType.UPDATE, OperationType.DELETE]:
raise PermissionDenied("Operation type UPDATE and DELETE only")
# do not allow to ask for a deletion if delete request already there
if instance.has_pending_delete_request:
raise PermissionDenied("A deletion request has already been submitted for this instance")

parameters = {
'operation': operation,
Expand Down
12 changes: 7 additions & 5 deletions templates/403.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
<h2 class="headline text-warning text-center">403</h2>
<div class="error-content align-content-center">
<h3><i class="fas fa-exclamation-triangle text-warning"></i> Access denied</h3>
<p>
The page you are trying to access has restricted access.
<br>
{{ exception }}
<p class="text-warning">
{% if exception %}
{{ exception }}
{% else %}
The page you are trying to access has restricted access.
{% endif %}
<br>
</p>

</div>
</div>
</section>
Expand Down
10 changes: 6 additions & 4 deletions templates/service_catalog/custom_columns/operation_request.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<a href="{% url 'service_catalog:instance_request_new_operation' instance_id=object.id operation_id=record.id %}"
class="btn btn-info bg-sm">
<i class="fas fa-shopping-cart"></i>
</a>
<div {% if object.has_pending_delete_request %}data-toggle='tooltip' data-placement='left' title='A deletion request has already been submitted for this instance'{% endif %}>
<a href="{% url 'service_catalog:instance_request_new_operation' instance_id=object.id operation_id=record.id %}"
class="btn btn-info bg-sm {% if object.has_pending_delete_request %}disabled{% endif %}">
<i class="fas fa-shopping-cart"></i>
</a>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ def test_customer_cannot_request_admin_operation(self):
response = self.client.post(url, data=data)
self.assertEqual(403, response.status_code)

def test_cannot_request_operation_when_deletion_already_asked(self):
self.test_request.operation = self.delete_operation_test
self.test_request.save()
args = {
'instance_id': self.test_instance.id,
'operation_id': self.delete_operation_test.id
}
data = {'text_variable': 'my_var'}
url = reverse('service_catalog:instance_request_new_operation', kwargs=args)
self.client.force_login(user=self.standard_user)
response = self.client.post(url, data=data)
self.assertEqual(403, response.status_code)

def test_cannot_request_non_available_instance(self):
for state in [InstanceState.PENDING, InstanceState.PROVISIONING, InstanceState.DELETING, InstanceState.DELETED]:
self.test_instance.state = state
Expand Down

0 comments on commit 47cf264

Please sign in to comment.