Skip to content

Commit

Permalink
Da/dropnfill (#1654)
Browse files Browse the repository at this point in the history
* adding drag and fill for component import

* client-side filetype checking

* client-side file size checking 5MB max. missing div.

* missing listed catalog for CMMC. Delete extra migration. adjust test for drag-n-fill. import_project_submit for import project view/test

* json_content not id_file

* spelling

* del

* hot fix for external catalogs
  • Loading branch information
davidpofo committed Jul 14, 2021
1 parent 586f28d commit f8aa034
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 21 deletions.
5 changes: 3 additions & 2 deletions controls/oscal.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def _list_catalog_files(self):
return self.extend_external_catalogs([
'NIST_SP-800-53_rev4_catalog.json',
'NIST_SP-800-53_rev5_catalog.json',
'NIST_SP-800-171_rev1_catalog.json'
'NIST_SP-800-171_rev1_catalog.json',
'CMMC_ver1_catalog.json'
], "files")

def _list_catalog_keys(self):
Expand Down Expand Up @@ -164,7 +165,7 @@ def _load_catalog_json(self):
oscal = data['catalog']
return oscal
elif os.path.isfile(catalog_file_external):
with open(catalog_file, 'r') as json_file:
with open(catalog_file_external, 'r') as json_file:
data = json.load(json_file)
oscal = data['catalog']
return oscal
Expand Down
8 changes: 4 additions & 4 deletions controls/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ def test_component_import_invalid_oscal(self):
self.click_element('a#component-import-oscal')
app_root = os.path.dirname(os.path.realpath(__file__))
oscal_json_path = os.path.join(app_root, "data/test_data", "test_invalid_oscal.json")
file_input = self.find_selected_option('input#id_file')
file_input = self.find_selected_option('input#json_content')
self.filepath_conversion(file_input, oscal_json_path, "sendkeys")

element_count_before_import = Element.objects.filter(element_type="system_element").count()
Expand Down Expand Up @@ -345,7 +345,7 @@ def test_component_import_oscal_json(self):
self.click_element('a#component-import-oscal')
app_root = os.path.dirname(os.path.realpath(__file__))
oscal_json_path = os.path.join(app_root, "data/test_data", "test_oscal_component.json")
file_input = self.find_selected_option('input#id_file')
file_input = self.find_selected_option('input#json_content')
oscal_json_path = self.filepath_conversion(file_input, oscal_json_path, "sendkeys")

self.click_element('input#import_component_submit')
Expand All @@ -366,7 +366,7 @@ def test_component_import_oscal_json(self):

wait_for_sleep_after(lambda: self.click_element('a#component-import-oscal'))

file_input = self.find_selected_option('input#id_file')
file_input = self.find_selected_option('input#json_content')
# Using converted keys from above
file_input.send_keys(oscal_json_path)

Expand Down Expand Up @@ -1162,7 +1162,7 @@ def test_update_project_json_import(self):
file_path = os.getcwd() + "/fixtures/test_project_import_data.json"
# convert filepath if necessary and send keys
self.filepath_conversion(file_input, file_path, "sendkeys")
self.browser.find_element_by_id("import_component_submit").click()
self.browser.find_element_by_id("import_project_submit").click()

# Check the new number of projects, and validate that it's the same
project_num = Project.objects.all().count()
Expand Down
64 changes: 64 additions & 0 deletions siteapp/static/css/govready-q.css
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,67 @@ form #id_appsource_compapp { width: 100%; overflow: auto !important; }
overflow: hidden!important;
}
}


/*drag n fill */

.file-droppable {
background: #d9d5ec;
border: dashed 2px #5b537d;
border-radius: 5px;
overflow: hidden;
transition: all 1s;
min-height: 70px;
position: relative;
}

.file-droppable.filled {
background: #c5dfdc;
border: solid 2px #6faca5;
border-radius: 5px;
}

.file-droppable:after {
position: absolute;
left: 13px;
top: 38px;
font-size: 10px;
font-weight: bold;
}

.file-droppable::before {
content: " ";
display: inline-block;
height: 100%;
width: 1%;
vertical-align: middle;
}

.file-droppable div {
display: inline-block;
vertical-align: middle;
padding: 10px;
overflow: hidden;
word-break: break-all;
}

.file-droppable span {
position: absolute;
font-weight: bold;
right: 5px;
top: -5px;
font-size: 20px;
cursor: pointer;
z-index: 10;
display: none;
}

.file-droppable input {
position: absolute;
z-index: 3;
display: block;
opacity: 0;
width: 100%;
height: 100%;
top: 0;
}
38 changes: 24 additions & 14 deletions templates/components/import-component-modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ <h4 class="modal-title" id="invitation_modal_title">Import OSCAL Component</h4>
</div>
<form id="component_import_form" action="{% url 'import_component' %}" onsubmit="show_spinner();" role="form" method="POST">{% csrf_token %}
<div class="modal-body">
<label for="{{import_form.file.id_auto}}">{{ import_form.file.label }}:</label>
{{ import_form.file }}
<br>
<label for="{{import_form.json_content.id_auto}}">{{ import_form.json_content.label }}:</label>
<br>
{% include "drag-n-fill.html" %}
{{ import_form.json_content }}
{{ import_form.import_name }}
<div class="modal-footer">
Expand All @@ -25,7 +21,8 @@ <h4 class="modal-title" id="invitation_modal_title">Import OSCAL Component</h4>
</form>

</div>
</div>
</div>
</div>

{% block scripts %}

Expand All @@ -37,15 +34,28 @@ <h4 class="modal-title" id="invitation_modal_title">Import OSCAL Component</h4>
}

function fillJSONContent(file) {
filecontents = $('#{{import_form.file.auto_id}}').prop('files')[0];
$('#{{import_form.import_name.auto_id}}').val(filecontents.name);
var reader = new FileReader();
reader.readAsText(filecontents);
reader.onload = function(e) {
$('#{{import_form.json_content.auto_id}}').val(e.target.result);
};
}
var fileInput = document.getElementById('json_content')

var filePath = fileInput.value;
var allowedExtensions =
/(\.json)$/i;
if (!allowedExtensions.exec(filePath)) {
fileInput.value = '';
show_modal_error("Wrong File Type Error", "Please only provide json data!");
} else {
filecontents = fileInput.files[0];
if (filecontents.size < 5000000) {
$('#{{import_form.import_name.auto_id}}').val(filecontents.name);
var reader = new FileReader();
reader.readAsText(filecontents);
reader.onload = function (e) {
$('#{{import_form.json_content.auto_id}}').val(e.target.result);
}
} else {
show_modal_error("File is too large", "Maximum size is under 5MBs");
}
}
}
function show_spinner() {
$("#import_loading_spinner").show();
}
Expand Down
2 changes: 1 addition & 1 deletion templates/controls/import_project_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ <h2 class="modal-title" id="import_project_modal_title">Select a Project</h2>
{{ import_project_form.json_content }}

<div class="modal-footer">
<input id="import_component_submit" class="btn btn-success btn-submit" type="submit" value="Import"/>
<input id="import_project_submit" class="btn btn-success btn-submit" type="submit" value="Import"/>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<img id="import_loading_spinner" src="{% static "img/icons/spinner.gif" %}"/>
</div>
Expand Down
40 changes: 40 additions & 0 deletions templates/drag-n-fill.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<div class="file-droppable">
<div>Drag-n-drop a file here</div>
<span>&times;</span>
<input type="file" id="json_content" />
</div>

{% block scripts %}
<script>
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll('.file-droppable').forEach(function(droppable) {
var originalText = droppable.querySelector('div').innerHTML;
var input = droppable.querySelector('input');
var fileChanged = function() {
var files = input.files;
if (files.length) {
droppable.querySelector('span').style.display = 'block';
droppable.querySelector('div').innerHTML = '';
for (var i = 0; i < files.length; i++) {
droppable.querySelector('div').innerHTML += files[i].name + '<br>';
}
droppable.classList.add('filled');
fillJSONContent(files)// file json box
} else {
droppable.querySelector('div').innerHTML = originalText;
droppable.classList.remove('filled');
droppable.querySelector('span').style.display = 'none';
}
};
input.addEventListener('change', fileChanged);
fileChanged(input);
droppable.querySelector('span').addEventListener('click', function() {
input.value = '';
fileChanged(input);
});
});

});
</script>

{% endblock %}

0 comments on commit f8aa034

Please sign in to comment.