Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop aspen poam demo #269

Open
wants to merge 53 commits into
base: develop-aspen
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
0c53ef9
Add initial code for spreadsheet-based POA&Ms
gregelin May 4, 2022
60d9317
Add file checks, better routing to POA&M spreadsheet import
gregelin May 5, 2022
2879826
Poam serializer, viewset endpoint, new react component for spreadshee…
SergioJFalcon May 5, 2022
f64eb86
Minor debugging changes
gregelin May 6, 2022
983ab49
spreadsheet poams for a single system
SergioJFalcon May 6, 2022
d4f2d5a
fix for duplicate data: id needs to be unique, used a counter in seri…
SergioJFalcon May 6, 2022
0656fd6
Filter spreadsheet POA&Ms by id
gregelin May 7, 2022
0e56197
Hide POA&M counts
gregelin May 7, 2022
b594c5d
Move poa&ms spreadsheet to settings page
gregelin May 7, 2022
5f19b12
Merge branch 'develop-aspen' into ge/develop-aspen-poam-spreadsheet
gregelin May 8, 2022
6d2664b
Remover "summary 2" dev label
gregelin May 8, 2022
6c4fbf8
Mock enhancement of spreadsheet POA&M data
gregelin May 8, 2022
ea4bf40
Link to POA&M datagrid fed by spreadsheet
gregelin May 8, 2022
2510a84
Change 'Template Library' to 'Questionnaires'
gregelin May 9, 2022
6c8f431
Remove icons from project listing.
gregelin May 9, 2022
f92c9ae
Patch dynamic summary_1 data
gregelin May 9, 2022
56e4dfa
Download POA&M spreadsheet from settings
gregelin May 9, 2022
8c350d1
Edit status and update local spreadsheet
SergioJFalcon May 9, 2022
e3e13fa
Merge branch 'ge/develop-aspen-poam-spreadsheet' of https://github.co…
SergioJFalcon May 9, 2022
80f84c9
Update choices for POA&M spreadsheet status
gregelin May 9, 2022
bbf15a1
merge ge/develop-aspen-poam-spreadsheet into fedramp-demo
gregelin May 11, 2022
fd726a9
merge request-ui into develop-aspen-fedramp-demo
gregelin May 11, 2022
e94b77e
Merge branch 'request-ui' into develop-aspen-fedramp-demo
gregelin May 11, 2022
66398af
Merge branch 'request-ui' into develop-aspen-fedramp-demo
gregelin May 11, 2022
4238835
Merge branch 'develop-aspen' into develop-aspen-fedramp-demo
gregelin May 19, 2022
13a74ba
Sync with devlop-aspen May 26
gregelin May 26, 2022
facdf47
Sync with devlop-aspen May 26 - fix controls/urls.py poams route
gregelin May 26, 2022
73607d7
Sync with develop-aspen
gregelin Jun 17, 2022
a66ea7d
Add form to create system from string or URLs
gregelin Jun 18, 2022
b6bbade
Fixes to create new system from string
gregelin Jun 18, 2022
ae9a69d
Draft UI tests for creating systems via string
gregelin Jun 18, 2022
ec39de2
Sketch of creating systems in Aspen
gregelin Jun 20, 2022
908d07c
Add by project template to new system, remove other links to project …
gregelin Jun 20, 2022
ac6de34
Develop aspen create system screens (#267)
gregelin Jun 21, 2022
587042d
Merge branch 'develop-aspen' into develop-aspen-ui
gregelin Jun 21, 2022
1c17b31
Replace dummy Aspen system info, add SystemEvents
gregelin Jun 21, 2022
c6ce869
Reorganize new system page
gregelin Jun 21, 2022
858b2cf
Aspen UI-classic, Aspen with classic UI look and feel
gregelin Jun 21, 2022
acd140f
Display imported POA&Ms on classic POA&M page.
gregelin Jun 21, 2022
a7dae28
Merge branch 'develop-aspen' into develop-aspen-fedramp-demo
gregelin Jun 21, 2022
cb8e74a
Merge branch 'develop-aspen-ui-classic' into develop-aspen-fedramp-demo
gregelin Jun 22, 2022
ff8795c
Use Template Library as link
gregelin Jun 22, 2022
777a1ec
Use Template Library as link
gregelin Jun 22, 2022
39459ff
Further synch with develop-aspen clean up
gregelin Jun 22, 2022
821514f
Update VERSION
gregelin Jun 22, 2022
610ca06
Fix tests
govreadydeploy Jun 23, 2022
ec3e2cb
Fix tests
govreadydeploy Jun 24, 2022
025cfe4
Fix tests 2
govreadydeploy Jun 24, 2022
53ea7b8
Merge branch 'develop-aspen-ui-classic' into develop-aspen-poam-demo
govreadydeploy Jun 24, 2022
b22ab48
Update VERSION
gregelin Jun 24, 2022
f2b7149
Merge branch 'develop-aspen-poam-demo' of github.com:GovReady/govread…
gregelin Jun 24, 2022
6b5a14f
Update sync with v0.10.1
gregelin Jun 27, 2022
79c3fc6
Sync with main v0.10.1.1-dev
gregelin Jun 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# GovReady-Q App
__pycache__/
/local
data/*
/modules/local
apps/
static_root/*
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ and provides a solid foundation for even more exciting innovations to come.

**UI changes**

* Change to Aspen UI.
* Change label 'certified statement' to 'reference statement'.
* Warning Message appears at the top of home page and login page while using an Internet Explorer browser informing the user of Internet Explorer not being supported.
* Indicate private components with lock icon.
Expand All @@ -68,6 +69,7 @@ and provides a solid foundation for even more exciting innovations to come.
* Only Component owner can edit user permissions.
* Display the control framework along side of controls in component control listing page.
* Remove icons from project listing.
* Change 'Template Library' to 'Questionnaires'.
* Add Component search filter to filter results to components owned by user.
* Add form to create system from string or URLs.
* Change language in interface to 'system, systems' instead of 'project, projects'.
Expand Down
64 changes: 61 additions & 3 deletions api/controls/serializers/poam.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import pathlib
import pandas
import structlog
from structlog import get_logger
from structlog.stdlib import LoggerFactory
from rest_framework import serializers
from api.base.serializers.types import ReadOnlySerializer
from api.controls.serializers.statements import DetailedStatementSerializer
from controls.models import Poam

from api.base.serializers.types import ReadOnlySerializer, WriteOnlySerializer
from api.controls.serializers.statements import DetailedStatementSerializer
from controls.models import Poam, System

structlog.configure(logger_factory=LoggerFactory())
logger = get_logger()
class SimplePoamSerializer(ReadOnlySerializer):
statement = serializers.SerializerMethodField('get_statement')

Expand Down Expand Up @@ -37,7 +44,58 @@ class Meta:
'remediation_plan', 'scheduled_completion_date', 'milestones','milestone_changes',
'risk_rating_original', 'risk_rating_adjusted', 'poam_group', 'statement']

class SimpleSpreadsheetPoamSerializer(ReadOnlySerializer):
spreadsheet_poams = serializers.SerializerMethodField('get_spreadsheet_poams')

def get_spreadsheet_poams(self, system):
print(2, "======== system.id, system", system.id, system)
poams_list = []
counter = 1;
fn = "local/poams_list.xlsx"
if pathlib.Path(fn).is_file():
try:
df_dict = pandas.read_excel(fn, header=1)
for index, row in df_dict.iterrows():
# import ipdb; ipdb.set_trace()
if system.id == row.get('CSAM ID', ""):
poam_dict = {
"id": index,
"csam_id": row.get('CSAM ID', ""),
"inherited": "No",
"org": row.get('Org', ""),
"sub_org": row.get('Sub Org', ""),
"system_name": row.get('System Name', ""),
"poam_id": row.get('POAM ID', "" ),
"poam_title": row.get('POAM Title', ""),
"system_type": row.get('System Type', ""),
"detailed_weakness_description": row.get('Detailed Weakness Description', ""),
"status": row.get('Status', "")
}
counter += 1
# Enhance data
# Test for control inheritance
inherited = "No"
if "CA-8" in row.get('POAM Title', ""):
poam_dict['inherited'] = "Yes"
poam_dict['system_name'] = f"{poam_dict['system_name']} inherits from Central Log Server"
poams_list.append(poam_dict)
except FileNotFoundError as e:
logger.error(f"Error reading file {fn}: {e}")
except Exception as e:
logger.error(f"Other Error reading file {fn}: {e}")
return poams_list
class Meta:
model = System
fields = ['spreadsheet_poams']

class SimpleUpdatePoamSpreadsheetSerializer(WriteOnlySerializer):
row = serializers.IntegerField(max_value=None, min_value=None)
column = serializers.CharField(min_length=None, max_length=None, allow_blank=True, trim_whitespace=True)
value = serializers.CharField(min_length=None, max_length=None, allow_blank=True, trim_whitespace=True)

class Meta:
model = System
fields = ['row', 'column', 'value']
class DetailedPoamSerializer(SimplePoamSerializer):
statement = DetailedStatementSerializer()

Expand Down
11 changes: 11 additions & 0 deletions api/controls/serializers/readiness_level.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from api.base.serializers.types import ReadOnlySerializer
from controls.models import Statement


class SimpleReadinessLevelSerializer(ReadOnlySerializer):

class Meta:
model = Element
fields = ['readiness_level']


4 changes: 2 additions & 2 deletions api/controls/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from rest_framework import routers
from rest_framework_nested.routers import NestedSimpleRouter
from api.controls.views.element import ElementViewSet, ElementWithPermissionsViewSet
from api.controls.views.system import SystemViewSet, SystemControlsViewSet, SystemAssessmentViewSet, SystemPoamViewSet
from api.controls.views.system import SystemViewSet, SystemControlsViewSet, SystemAssessmentViewSet, SystemPoamViewSet, SystemPoamSpreadsheetViewSet

router = routers.DefaultRouter()
router.register(r'elements', ElementViewSet)
Expand All @@ -14,7 +14,7 @@
systems_router.register(r'controls', SystemControlsViewSet, basename='systems-controls')
systems_router.register(r'assessments', SystemAssessmentViewSet, basename='systems-assessments')
systems_router.register(r'poams', SystemPoamViewSet, basename='systems-poams')

systems_router.register(r'spreadsheet-poams', SystemPoamSpreadsheetViewSet, basename='systems-spreadsheet-poams')
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^', include(systems_router.urls))
Expand Down
48 changes: 47 additions & 1 deletion api/controls/views/system.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from os import system
import pathlib
import pandas
from openpyxl import load_workbook
from rest_framework.decorators import action
from rest_framework.response import Response

from api.base.views.base import SerializerClasses
from api.base.views.viewsets import ReadOnlyViewSet
from api.controls.serializers.element import SimpleElementControlSerializer, DetailedElementControlSerializer
from api.controls.serializers.poam import DetailedPoamSerializer, SimplePoamSerializer
from api.controls.serializers.poam import DetailedPoamSerializer, SimplePoamSerializer, SimpleSpreadsheetPoamSerializer, SimpleUpdatePoamSpreadsheetSerializer
from api.controls.serializers.system import DetailedSystemSerializer, SimpleSystemSerializer, SystemCreateAndSetProposalSerializer, SystemRetrieveProposalsSerializer
from api.controls.serializers.system_assement_results import DetailedSystemAssessmentResultSerializer, \
SimpleSystemAssessmentResultSerializer
Expand Down Expand Up @@ -71,3 +75,45 @@ class SystemPoamViewSet(ReadOnlyViewSet):

NESTED_ROUTER_PKS = [{'pk': 'systems_pk', 'model_field': 'statement.consumer_element.system'}]

class SystemPoamSpreadsheetViewSet(ReadOnlyViewSet):
queryset = System.objects.all()
# queryset = System.objects.filter(pk=9)
serializer_classes = SerializerClasses(
retrieve=SimpleSpreadsheetPoamSerializer,
list=SimpleSpreadsheetPoamSerializer,
updateSpreadsheet=SimpleUpdatePoamSpreadsheetSerializer)

@action(detail=True, url_path="updateSpreadsheet", methods=["PUT"])
def updateSpreadsheet(self, request, **kwargs):
system, validated_data = self.validate_serializer_and_get_object(request)
for key, value in validated_data.items():
if key == 'row':
row = value
if key == 'column':
column = value
if key == 'value':
value = value
print(row, column, value)

system.save()
fn = "local/poams_list.xlsx"
#load excel file
workbook = load_workbook(filename=fn)
sheet = workbook.active

#open workbook
colNames = {}
current = 0
for col in sheet.iter_cols(min_row=2, max_row=2, min_col=1, max_col=sheet.max_column):
colNames[col[0].value.lower()] = current
current += 1

#modify the desired cell
sheet.cell(row=row+2, column=colNames[column]+1).value = value

#save the file
workbook.save(fn)

serializer_class = self.get_serializer_class('updateSpreadsheet')
serializer = self.get_serializer(serializer_class, system)
return Response(serializer.data)
6 changes: 5 additions & 1 deletion controls/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@
url(r'^statement_history/(?P<smt_id>.*)/$', views.statement_history, name="statement_history"),
url(r'^restore_to/(?P<smt_id>.*)/(?P<history_id>.*)/$', views.restore_to_history, name="restore_to"),

url(r'^(?P<system_id>.*)/aspen/summary/fake$', views.system_summary_1_aspen, name="system_summary_1"),
url(r'^(?P<system_id>.*)/aspen/summary$', views.system_summary_aspen, name="system_summary"),
url(r'^(?P<system_id>.*)/aspen/summary/fake$', views.system_summary_1_aspen, name="system_summary_1"),
url(r'^(?P<system_id>.*)/aspen/integrations$', views.system_integrations_aspen, name="system_integrations"),

url(r'^(?P<system_id>.*)/aspen/summary/poams$', views.system_poams_aspen, name="system_summary_poams"),
url(r'^import-poams$', views.import_poams_xlsx, name="import_poams_xlsx"),
url(r'^export-poams-xlsx$', views.export_poams_xlsx, name="export_poams_xlsx"),

url(r'^new', views.create_system_from_string, name="create_system_from_string"),

# Systems Assessment Results
Expand Down
15 changes: 15 additions & 0 deletions controls/utils/views_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from api.siteapp.serializers.projects import DetailedProjectsSerializer
from django.db import transaction
from siteapp.models import Project, ProjectMembership
from controls.models import Element, System, Statement, Deployment

import logging
logging.basicConfig()
import structlog
from structlog import get_logger
from structlog.stdlib import LoggerFactory

structlog.configure(logger_factory=LoggerFactory())
structlog.configure(processors=[structlog.processors.JSONRenderer()])
logger = get_logger()

21 changes: 13 additions & 8 deletions controls/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3302,14 +3302,6 @@ def poams_list(request, system_id):
controls = system.root_element.controls.all()
poam_smts = system.root_element.statements_consumed.filter(statement_type="POAM").order_by('-updated')


# impl_smts_count = {}
# ikeys = system.smts_control_implementation_as_dict.keys()
# for c in controls:
# impl_smts_count[c.oscal_ctl_id] = 0
# if c.oscal_ctl_id in ikeys:
# impl_smts_count[c.oscal_ctl_id] = len(system.smts_control_implementation_as_dict[c.oscal_ctl_id]['control_impl_smts'])

# Return the controls
context = {
"system": system,
Expand Down Expand Up @@ -4340,6 +4332,19 @@ def import_poams_xlsx(request):
messages.add_message(request, messages.ERROR, f"POA&Ms spreadsheet file required.")
return JsonResponse({ "status": "ok", "redirect": redirect_url })

@login_required
@transaction.atomic
def export_poams_xlsx(request):

from django.utils.encoding import smart_str

poams_xlsx_filepath = "local/poams_list.xlsx"
file_name = f"poams_list_{datetime.now().strftime('%Y-%m-%d-%H-%M')}.xlsx"
path = open(poams_xlsx_filepath, 'rb')
response = HttpResponse(path, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') # mimetype is replaced by content_type for django 1.7
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
return response

# System Deployments
@login_required
def system_deployments_aspen(request, system_id):
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/components/system-summary/component.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import { SystemSummary } from './system_summary';
import { SystemSummarySpreadsheet } from './system_summary_spreadsheet';
import { Provider } from "react-redux";
import store from "../../store";

Expand All @@ -11,4 +12,13 @@ window.system_summary = ( systemId, projectId ) => {
</Provider>,
document.getElementById('system-summary-poam-datagrid')
);
};

window.system_summary_spreadsheet = ( systemId, projectId ) => {
ReactDOM.render(
<Provider store={store}>
<SystemSummarySpreadsheet systemId={systemId} projectId={projectId} />
</Provider>,
document.getElementById('system-summary-poam-spreadsheet-datagrid')
);
};
Loading