Skip to content

Commit

Permalink
Merge pull request #1441 from GovReady/da/fix_edit_comp
Browse files Browse the repository at this point in the history
Fixed component library name/description edit
  • Loading branch information
davidpofo authored Feb 28, 2021
2 parents e38694d + 7f48851 commit d0daf99
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 36 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ GovReady-Q Release Notes
v999 (February XX, 2021)
------------------------

**Developer changes**

* Created a ElementEditForm Django form in conjunction with some functional changes to avoid name collisions issues with component library.

**Feature changes**

* Remove a component and its statements from a system.
Expand Down Expand Up @@ -49,7 +53,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.
Expand Down
5 changes: 5 additions & 0 deletions controls/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down
2 changes: 1 addition & 1 deletion controls/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
url(r'^import_records/(?P<import_record_id>.*)/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<catalog_key>.*)/group/(?P<g_id>.*)', views.group, name="control_group"),
Expand Down
53 changes: 28 additions & 25 deletions controls/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"})
# 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"})

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() })
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):
"""
Expand Down Expand Up @@ -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}
)

Expand Down Expand Up @@ -1692,7 +1696,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."
Expand Down Expand Up @@ -2587,7 +2591,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
Expand Down Expand Up @@ -2666,7 +2670,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",
Expand Down
6 changes: 4 additions & 2 deletions templates/components/element_detail_tabs.html
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,12 @@ <h4 id="panel-panel_num-title" class="panel-title">
}
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"){
Expand Down
2 changes: 1 addition & 1 deletion templates/components/element_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ <h2>New Component (aka Element)</h2>
<div class="well">
<form method="post">
{% csrf_token %}
<input type=hidden name=action value=neworg>
<input type=hidden name=action value=newele>
{% bootstrap_form form %}
<p><button type="submit" id="create-portfolio-button" class="btn btn-success">Create &raquo;</button></p>
</form>
Expand Down
12 changes: 6 additions & 6 deletions templates/edit-component-modal.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<div id="edit-component-modal" class="modal"">
<div id="edit-component-modal" class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="invitation_modal_title">Edit Component</h4>
</div>
<form role="form" method="get">
<form role="form" method="POST">
<div class="modal-body">
<div class="form-group" data-children-count="1">
<label class="control-label" for="id_name">Name</label>
Expand All @@ -14,7 +14,7 @@ <h4 class="modal-title" id="invitation_modal_title">Edit Component</h4>
</div>
<div class="form-group" data-children-count="1">
<label class="control-label" for="id_name">Description</label>
<input type="text" name="name" maxlength="250" class="form-control" placeholder="Description" title="Common name or acronym of the element" required="" id="description-input" data-kwimpalastatus="alive" data-kwimpalaid="1609952239310-0">
<input type="text" name="name" maxlength="250" class="form-control" placeholder="Description" title="Brief description of the Element" required="" id="description-input" data-kwimpalastatus="alive" data-kwimpalaid="1609952239310-0">
<div class="help-block">Brief description of the Element</div>
</div>
<div class="alert alert-danger" role="alert" id="error-alert">
Expand All @@ -28,8 +28,8 @@ <h4 class="modal-title" id="invitation_modal_title">Edit Component</h4>
</div>
</div>
</div>
</div>


{% block scripts %}
<script>
function show_edit_component_modal(name,description,callback) {
Expand All @@ -46,7 +46,7 @@ <h4 class="modal-title" id="invitation_modal_title">Edit Component</h4>
$('#edit-component-modal').modal('hide');
}
function show_edit_component_modal_error(errorMessage){
$("#error-alert").html(errorMessage);
$("#error-alert").html(errorMessage);
$('#error-alert').fadeIn();
}
</script>
Expand Down

0 comments on commit d0daf99

Please sign in to comment.