1616from django .core .exceptions import PermissionDenied
1717from django .contrib .auth .decorators import user_passes_test
1818
19- from dojo .models import Finding , System_Settings , Test , Dojo_User , Note_Type , NoteHistory , Notes
19+ from dojo .models import Finding , System_Settings , Test , Dojo_User , Note_Type , NoteHistory , Notes , Sonarqube_Issue
2020from dojo .forms import GoogleSheetFieldsForm
2121from dojo .utils import add_breadcrumb , Product_Tab
2222
@@ -39,6 +39,7 @@ def configure_google_sheets(request):
3939 else :
4040 initial ['Protect ' + field .name ] = True
4141 initial ['drive_folder_ID' ] = system_settings .drive_folder_ID
42+ initial ['email_address' ] = system_settings .email_address
4243 initial ['enable_service' ] = system_settings .enable_google_sheets
4344 form = GoogleSheetFieldsForm (all_fields = fields , initial = initial , credentials_required = False )
4445 else :
@@ -53,6 +54,7 @@ def configure_google_sheets(request):
5354 system_settings .column_widths = ""
5455 system_settings .credentials = ""
5556 system_settings .drive_folder_ID = ""
57+ system_settings .email_address = ""
5658 system_settings .enable_google_sheets = False
5759 system_settings .save ()
5860 messages .add_message (
@@ -92,6 +94,7 @@ def configure_google_sheets(request):
9294 system_settings .column_widths = column_widths
9395 system_settings .credentials = cred_str
9496 system_settings .drive_folder_ID = drive_folder_ID
97+ system_settings .email_address = form .cleaned_data ['email_address' ]
9598 system_settings .enable_google_sheets = form .cleaned_data ['enable_service' ]
9699 system_settings .save ()
97100 if initial :
@@ -261,9 +264,15 @@ def export_to_sheet(request, tid):
261264 except googleapiclient .errors .HttpError as error :
262265 error_message = 'There is a problem with the Google Sheets Sync Configuration. Contact your system admin to solve the issue.'
263266 return render (request , 'google_sheet_error.html' , {'error_message' : error_message })
267+ except Exception as e :
268+ error_message = e
269+ return render (request , 'google_sheet_error.html' , {'error_message' : error_message })
264270
265271
266272def create_googlesheet (request , tid ):
273+ user_email = request .user .email
274+ if not user_email :
275+ raise Exception ('User must have an email address to use this feature.' )
267276 test = Test .objects .get (id = tid )
268277 system_settings = get_object_or_404 (System_Settings , id = 1 )
269278 service_account_info = json .loads (system_settings .credentials )
@@ -289,7 +298,7 @@ def create_googlesheet(request, tid):
289298 addParents = folder_id ,
290299 removeParents = previous_parents ,
291300 fields = 'id, parents' ).execute ()
292- user_email = request . user . email
301+ # Share created Spreadsheet with current user
293302 drive_service .permissions ().create (body = {'type' : 'user' , 'role' : 'writer' , 'emailAddress' : user_email }, fileId = spreadsheetId ).execute ()
294303 populate_sheet (tid , spreadsheetId )
295304
@@ -311,7 +320,10 @@ def sync_findings(request, tid, spreadsheetId):
311320 sheet_names .append (date )
312321 except :
313322 pass
314- sheet_title = str (max (sheet_names ))
323+ try :
324+ sheet_title = str (max (sheet_names ))
325+ except :
326+ raise Exception ('Existing Google Spreadsheet has errors. Delete the speadsheet and export again.' )
315327 res ['sheet_title' ] = sheet_title
316328
317329 result = sheets_service .spreadsheets ().values ().get (spreadsheetId = spreadsheetId , range = sheet_title ).execute ()
@@ -443,6 +455,7 @@ def populate_sheet(tid, spreadsheetId):
443455 system_settings = get_object_or_404 (System_Settings , id = 1 )
444456 service_account_info = json .loads (system_settings .credentials )
445457 service_account_email = service_account_info ['client_email' ]
458+ email_address = system_settings .email_address
446459 SCOPES = ['https://www.googleapis.com/auth/spreadsheets' ]
447460 credentials = service_account .Credentials .from_service_account_info (service_account_info , scopes = SCOPES )
448461 sheets_service = googleapiclient .discovery .build ('sheets' , 'v4' , credentials = credentials , cache_discovery = False )
@@ -548,6 +561,7 @@ def populate_sheet(tid, spreadsheetId):
548561 "editors" : {
549562 "users" : [
550563 service_account_email ,
564+ email_address
551565 ]
552566 },
553567 # "description": "Protecting total row",
@@ -618,6 +632,7 @@ def populate_sheet(tid, spreadsheetId):
618632 "editors" : {
619633 "users" : [
620634 service_account_email ,
635+ email_address
621636 ]
622637 },
623638 "warningOnly" : False
@@ -745,13 +760,14 @@ def populate_sheet(tid, spreadsheetId):
745760 "editors" : {
746761 "users" : [
747762 service_account_email ,
763+ email_address
748764 ]
749765 },
750766 "warningOnly" : False
751767 }
752768 }
753769 })
754- elif column_name [:6 ] == '[note]' :
770+ elif column_name [:6 ] == '[note]' or column_name [: 11 ] == '[duplicate]' :
755771 body ["requests" ].append ({
756772 "autoResizeDimensions" : {
757773 "dimensions" : {
@@ -767,6 +783,7 @@ def populate_sheet(tid, spreadsheetId):
767783
768784def get_findings_list (tid ):
769785 test = Test .objects .get (id = tid )
786+ system_settings = get_object_or_404 (System_Settings , id = 1 )
770787 findings = Finding .objects .filter (test = test ).order_by ('numerical_severity' )
771788 active_note_types = Note_Type .objects .filter (is_active = True ).order_by ('id' )
772789 note_type_activation = active_note_types .count ()
@@ -783,11 +800,15 @@ def get_findings_list(tid):
783800 for finding in findings :
784801 finding_details = []
785802 for field in fields :
786- value = eval ( " finding." + field .name )
803+ value = getattr ( finding , field .name )
787804 if type (value ) == datetime .date or type (value ) == Test or type (value ) == datetime .datetime :
788- var = str (eval ( "finding." + field . name ) )
805+ var = str (value )
789806 elif type (value ) == User or type (value ) == Dojo_User :
790807 var = value .username
808+ elif type (value ) == Finding :
809+ var = value .id
810+ elif type (value ) == Sonarqube_Issue :
811+ var = value .key
791812 else :
792813 var = value
793814 finding_details .append (var )
@@ -856,6 +877,29 @@ def get_findings_list(tid):
856877 for i in range (missing_notes_count ):
857878 findings_list [f + 1 ].append ('' )
858879 findings_list [f + 1 ].append ('' )
880+
881+ if system_settings .enable_deduplication :
882+ if note_type_activation :
883+ for note_type in active_note_types :
884+ findings_list [0 ].append ('[duplicate] ' + note_type .name )
885+ for f in range (findings .count ()):
886+ original_finding = findings [f ].duplicate_finding
887+ for note_type in active_note_types :
888+ try :
889+ note = original_finding .notes .filter (note_type = note_type ).latest ('date' )
890+ findings_list [f + 1 ].append (note .entry )
891+ except :
892+ findings_list [f + 1 ].append ('' )
893+ else :
894+ findings_list [0 ].append ('[duplicate] note' )
895+ for f in range (findings .count ()):
896+ original_finding = findings [f ].duplicate_finding
897+ try :
898+ note = original_finding .notes .latest ('date' )
899+ findings_list [f + 1 ].append (note .entry )
900+ except :
901+ findings_list [f + 1 ].append ('' )
902+
859903 findings_list [0 ].append ('Last column' )
860904 for f in range (findings .count ()):
861905 findings_list [f + 1 ].append ('-' )
0 commit comments