From 3afb56ed07f2d9e2b021a8cd6f9611552ea57e93 Mon Sep 17 00:00:00 2001 From: davidpofo Date: Sat, 27 Feb 2021 14:59:16 -0500 Subject: [PATCH 1/3] edit_element since we can edit more than the name with rename_element func. Fix name collision issue when trying to update the description of an element with new element edit form. a couple odds and ends. --- CHANGELOG.md | 1 - controls/forms.py | 5 ++ controls/urls.py | 2 +- controls/views.py | 63 ++++++++++--------- templates/components/element_detail_tabs.html | 6 +- templates/components/element_form.html | 2 +- templates/edit-component-modal.html | 12 ++-- 7 files changed, 50 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9253046e..d41b2f1d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,6 @@ Project page displays mini-dashboard of compliance stats. * Properly restrict statement history access to users with system, staff, or admin permissions. * Avoid name collisions when cloning a component. * Replaced function-based views with class-based listview for SelectedComponentsList, ProjectList. -* Avoid name collisions when cloning a component. * Default to not use Django Debug Toolbar. Added new `enable_tool_bar` parameter option for `local/environment.json` to allow users to enable(True) or disable(False) the Django Debug Toolbar. * Adding DummyCache to prevent real caching while running automated tests. * Refactored use of random package to use secure secrets module. diff --git a/controls/forms.py b/controls/forms.py index 745d87f64..e9bed40af 100644 --- a/controls/forms.py +++ b/controls/forms.py @@ -80,6 +80,11 @@ def clean(self): raise ValidationError("Component (aka Element) name {} not available.".format(cd['name'])) return cd +class ElementEditForm(ModelForm): + + class Meta: + model = Element + fields = ['id', 'name', 'description'] class ImportOSCALComponentForm(forms.Form): file = forms.FileField(label="Select OSCAL file (.json)", diff --git a/controls/urls.py b/controls/urls.py index 8e220f649..05aef5230 100644 --- a/controls/urls.py +++ b/controls/urls.py @@ -76,7 +76,7 @@ url(r'^import_records/(?P.*)/delete$', views.import_record_delete, name="import_record_delete"), # Elements - url(r'^elements/(\d+)/__rename$', views.rename_element, name="rename_element"), + url(r'^elements/(\d+)/__edit$', views.edit_element, name="edit_element"), # Controls url(r'^catalogs/(?P.*)/group/(?P.*)', views.group, name="control_group"), diff --git a/controls/views.py b/controls/views.py index 4afdfb91c..485b273db 100644 --- a/controls/views.py +++ b/controls/views.py @@ -29,9 +29,9 @@ from siteapp.forms import ProjectForm from siteapp.models import Project from system_settings.models import SystemSettings -# from .forms import ImportOSCALComponentForm -# from .forms import StatementPoamForm, PoamForm, ElementForm, DeploymentForm -from .forms import * +from .forms import ImportOSCALComponentForm +from .forms import StatementPoamForm, PoamForm, ElementForm, DeploymentForm +from .forms import ElementEditForm from .models import * from .utilities import * from simple_history.utils import update_change_reason @@ -212,33 +212,37 @@ def controls_updated(request, system_id): # User does not have permission to this system raise Http404 -def rename_element(request,element_id): - """Update the component's name + +@login_required +def edit_element(request, element_id): + """ + Edit Element information as long as the name does not clash with a different element name Args: request ([HttpRequest]): The network request component_id ([int|str]): The id of the component Returns: [JsonResponse]: Either a ok status or an error """ - try: + + # The original element(component) + ele_instance = get_object_or_404(Element, id=element_id) + + if request.method == 'POST': new_name = request.POST.get("name", "").strip() or None - new_description = request.POST.get("description", "").strip() or None - - if Element.objects.filter(name=new_name).exists() is True: - return JsonResponse({ "status": "err", "message": "Name already in use"}) - - element = get_object_or_404(Element, id=element_id) - element.name = new_name - element.description = new_description - element.save() - logger.info( - event="rename_element", - element={"id": element.id, "new_name": new_name, "new_description": new_description} - ) - return JsonResponse({ "status": "ok" }) - except: - import sys - return JsonResponse({ "status": "err", "message": sys.exc_info() }) + + # Check if the new component name is already in use and if the new name is different from the current name + if Element.objects.filter(name__iexact=new_name).exists() and new_name != ele_instance.name: + return JsonResponse({"status": "err", "message": "Name already in use"}) + + form = ElementEditForm(request.POST or None, instance=ele_instance) + if form.is_valid(): + logger.info( + event="edit_element", + object={"object": "element", "id": form.instance.id, "name": form.instance.name}, + user={"id": request.user.id, "username": request.user.username} + ) + form.save() + return JsonResponse({"status": "ok"}) class SelectedComponentsList(ListView): """ @@ -732,7 +736,7 @@ def system_element_remove(request, system_id, element_id): # Log result logger.info( event="change_system remove_component permission_denied", - object={"object": "component", "id": element.id}, + object={"object": "component", "id": element_id}, user={"id": request.user.id, "username": request.user.username} ) @@ -850,9 +854,9 @@ def component_library_component_copy(request, element_id): # Retrieve element element = Element.objects.get(id=element_id) count = Element.objects.filter(uuid=element.uuid).count() - + if count > 0: - e_copy = element.copy(name=element.name + " copy ("+str(count+1)+')') + e_copy = element.copy(name=element.name + " copy ("+str(count+1)+')') else: e_copy = element.copy() @@ -936,7 +940,7 @@ def restore_to_history(request, smt_id, history_id): # Check permission raise_404_if_not_permitted_to_statement(request, smt, 'change_system') - + full_smt_history = None for query_key in request.POST: if "restore" in query_key: @@ -1685,7 +1689,7 @@ def update_smt_prototype(request): statement = get_object_or_404(Statement, pk=form_values['smt_id']) # Check permission - raise_404_if_not_permitted_to_modify_statement(request, statement) + raise_404_if_not_permitted_to_statement(request, statement) if statement is None: statement_msg = "The id for this statement is no longer valid in the database." @@ -2580,7 +2584,7 @@ def project_import(request, project_id): if request.method == 'POST': project_data = request.POST['json_content'] # Need to get or create the app source by the id of the given app source - module_name = json.loads(project_data).get('project').get('module').get('key') + #module_name = json.loads(project_data).get('project').get('module').get('key') title = json.loads(project_data).get('project').get('title') system_root_element.name = title importcheck = False @@ -2659,7 +2663,6 @@ def project_import(request, project_id): risk_rating_original = poam.get('risk_rating_original'), scheduled_completion_date = poam.get('scheduled_completion_date'), weakness_detection_source = poam.get('weakness_detection_source'), weakness_name = poam.get('weakness_name'), weakness_source_identifier = poam.get('weakness_source_identifier'), poam_group = poam.get('poam_group')) - poam.save() poam_num += 1 logger.info( event="Poam import", diff --git a/templates/components/element_detail_tabs.html b/templates/components/element_detail_tabs.html index 44da07981..7150d40b3 100644 --- a/templates/components/element_detail_tabs.html +++ b/templates/components/element_detail_tabs.html @@ -473,10 +473,12 @@

} function edit_component() { show_edit_component_modal("{{element.name}}","{{element.description}}",(newName, newDescription)=>{ + ajax_with_indicator({ - url: '{% url "rename_element" element.id %}', + + url: '{% url "edit_element" element.id %}', method: "POST", - data: {name: newName,description: newDescription}, + data: {name: newName, description: newDescription}, keep_indicator_forever: true, success: function(res) { if(res["status"]=="ok"){ diff --git a/templates/components/element_form.html b/templates/components/element_form.html index 8268de113..3bd9deef2 100644 --- a/templates/components/element_form.html +++ b/templates/components/element_form.html @@ -18,7 +18,7 @@

New Component (aka Element)

{% csrf_token %} - + {% bootstrap_form form %}

diff --git a/templates/edit-component-modal.html b/templates/edit-component-modal.html index 829a6323f..4a7448139 100644 --- a/templates/edit-component-modal.html +++ b/templates/edit-component-modal.html @@ -1,11 +1,11 @@ -