def get_path_to_projects(): """Call the Path2User functionality of Geni for list based on a project""" LOGGER.debug("get_path_to_projects") email = request.args.get('email') other_id = request.args.get('otherId') project_id = request.args.get('project_id') source_profile_id = request.args.get('sourceProfile') (session['access_token'], session['refresh_token'], project_name, project_url, guids) = get_geni_project_guids(session['access_token'], session['refresh_token'], project_id) LOGGER.info( "get_path_to_projects params: email: %s other_id: %s project_id: %s source_profile_id: %s", email, other_id, project_id, source_profile_id) if (len(guids) > 0): if (source_profile_id is not None and len(source_profile_id) > 2): return handleSet(email, False, source_profile_id, guids, project_name, project_url, True) else: return handleSet(email, True, other_id, guids, project_name, project_url, True) else: data['subject'] = "Project " + project_id + " was empty." data['status'] = 'Empty project' data['error'] = {} data['error']['message'] = "Could not process empty project." sendErrorEmail(email, data)
def git_pull(repo): try: repo_remote = repo.remote('origin') repo_remote.pull() except Exception as e: log.logger.error("Exception occurred while pulling code", exc_info=True) mail.sendErrorEmail("Threat Model: Exception occurred while pulling code", e) raise e
def git_push(repo, message, files): try: repo.index.add(files) repo.index.commit(message) repo_remote = repo.remote('origin') repo_remote.push() except Exception as e: log.logger.error("Exception occurred while pushing code", exc_info=True) mail.sendErrorEmail("Threat Model: Exception occurred while pushing code", e) raise e
def create_p2u_background_job(params): """Builds long running job""" global LOGGER if LOGGER == None: LOGGER = logging.getLogger() LOGGER.debug("create_p2u_background_job") LOGGER.info( 'process path to user calling get_geni_path_to with params: %s', params['other_id']) continue_flag = True data = {} if params['other_id'] != params['target_profile_id']: while continue_flag: data = get_geni_path_to(params['access_token'], params['refresh_token'], params['other_id'], params['target_profile_id']) LOGGER.debug('Path data returned: %s', str(data)) if (data and str(data.get('status', '')) != 'pending'): continue_flag = False else: time.sleep(10) data['source_id'] = params['other_id'] data['target_id'] = params['target_profile_id'] if (str(data.get('status')) == 'done'): params['access_token'] = data['access_token'] params['refresh_token'] = data['refresh_token'] # load source and target names (params['access_token'], params['refresh_token'], source_obj) = get_other_profile(params['access_token'], params['refresh_token'], params['other_id']) profile_data = json.loads(source_obj) LOGGER.info('Source profile data returned: %s', source_obj) data['source_name'] = profile_data.get('name', '(unknown)') data['source_url'] = profile_data['profile_url'] (params['access_token'], params['refresh_token'], target_obj) = get_other_profile(params['access_token'], params['refresh_token'], params['target_profile_id']) profile_data = json.loads(target_obj) LOGGER.info('Target profile data returned: %s', target_obj) data['target_name'] = profile_data['name'] data['target_url'] = profile_data['profile_url'] # TODO - handle error case for API sendEmail(params['email'], data) else: if (not data.get('status')): data['status'] = 'API Error' sendErrorEmail(params['email'], data) else: data['status'] = 'Source and target profiles cannot be the same' data['source_id'] = params['other_id'] data['target_id'] = params['target_profile_id']
def git_clone(remote_path, local_path): try: repo = Repo.clone_from( remote_path, local_path, branch='master' ) return repo except Exception as e: log.logger.error("Exception occurred while cloning code", exc_info=True) mail.sendErrorEmail("Threat Model: Exception occurred while cloning code", e) raise e
def read_json(threatJasonPath): try: # read the Threat Dragon JSON file JSON_file = open(threatJasonPath, 'r') dataTM = JSON_file.read() JSON_file.close() # return a dictionary obj = json.loads(dataTM) return obj except FileNotFoundError as e2: log.logger.error("File not accessible") mail.sendErrorEmail("Threat Model: Exception occurred reading the JSON file", e) log.logger.info(f'Finish processing \n') raise e2 except Exception as e: log.logger.error("Exception occurred", exc_info=True) mail.sendErrorEmail("Threat Model: Exception occurred reading the JSON file", e) log.logger.info(f'Finish processing \n') raise e
def create_single_path_background_job(params): """Builds job to run one path on a worker""" global LOGGER if LOGGER == None: LOGGER = logging.getLogger() LOGGER.debug("create_single_path_background_job") continue_flag = True set_data = {} while continue_flag: set_data = get_geni_path_to(params['access_token'], params['refresh_token'], params['other_id'], params['guid']) LOGGER.debug('Path data returned: %s', str(set_data)) if (not set_data.get('status') or (set_data.get('status') and str(set_data['status']) != 'pending')): continue_flag = False else: time.sleep(10) (params['access_token'], params['refresh_token'], target_text) = get_other_profile(params['access_token'], params['refresh_token'], params['guid']) profile_data = json.loads(target_text) LOGGER.debug('Target profile data returned: %s', target_text) set_data['target_name'] = profile_data['name'] set_data['target_url'] = profile_data['profile_url'] if (str(set_data['status']) != 'not found' and str(set_data['status']) != 'done'): set_data['source_id'] = params['other_id'] set_data['target_id'] = params['guid'] set_data['step_count'] = 1000 sendErrorEmail(params['email'], set_data) elif (str(set_data['status']) == 'not found'): set_data['source_id'] = params['other_id'] set_data['target_id'] = params['guid'] set_data['step_count'] = 1000 if (not set_data.get('step_count')): set_data['step_count'] = 1000 return set_data
def doRequest(action, url, params="", data=""): try: auth = HTTPBasicAuth(user, passwd) headers = { 'Accept': 'application/json', 'Content-type':'application/json' } # Convert data to json send obj = json.dumps(data) r = requests.request( action, url, headers=headers, auth=auth, params=params, data=obj ) return json.loads(r.text) except Exception as e: log.logger.error("Exception occurred", exc_info=True) mail.sendErrorEmail("Threat Model: Exception occurred in the third party integration", e)
def parseJson(obj, threatJasonPath): try: global projectJiraKey global epicJiraKey processJSON = False receiver = [] # Check if we have the emails of the owner and reviewer if 'summary' in obj and 'owner' in obj['summary']: receiver.append(obj['summary']['owner']) else: receiver.append("") if 'detail' in obj and 'reviewer' in obj['detail']: receiver.append(obj['detail']['reviewer']) else: receiver.append("") receiver = ','.join(filter(None, receiver)) # Process the JSON files for (i) in obj['detail']['diagrams']: # Check if we have JSON files from Threat Dragon with a Jira key processJSON = checkTitle(i['title']) if processJSON: log.logger.info( f'Start processing {threatJasonPath} :: {projectJiraKey} (Jira) :: {epicJiraKey} (Epic) ' ) for (j) in i['diagramJson']['cells']: print("ID: " + j['id']) print("Type: " + j['type']) # We need to exclude boundary types? if j['type'] != 'tm.Boundary': # We have examples with id and not with ruleId if 'threats' in j: print("Has Threats: yes") for (k) in j['threats']: finalDesc = "No description" if 'description' in k: finalDesc = k['description'] else: k['description'] = "" finalMiti = "No Mitigation" if 'mitigation' in k: finalMiti = "Mitigation:\n" + k[ 'mitigation'] strJiraKey = checkDescription(finalDesc) if strJiraKey == "New": lblType = "STRIDE-" + k['type'].replace( " ", "_") titleInJira = handleTitle( k['title'], k['status']) jsonJira = { "fields": { "project": { "key": projectJiraKey }, "summary": titleInJira, "description": handleDescription( finalDesc, finalMiti), "issuetype": { "name": "Story" }, "customfield_10002": epicJiraKey, "labels": ["Threat", lblType], "priority": { "name": handleSeverity(k['severity']) } } } # Function to create issues res = third_party_integration.create_issue( jsonJira) # Check if the call was successful to insert the issue key if 'errorMessages' in res: log.logger.error( f"Request has failed for {titleInJira}" ) if len(res['errorMessages']) > 0: log.logger.error( f"{res['errorMessages']}") else: log.logger.error( f"{res['errors']}") else: k['description'] = '[' + res[ 'key'] + '] ' + k['description'] else: if k['status'] != "Mitigated": # Function to get issues res = third_party_integration.get_issue( strJiraKey) # Check if the call was successful to update the status to Mitigated if 'errorMessages' in res: log.logger.error( f"Request has failed for {strJiraKey}" ) if len(res['errorMessages']) > 0: log.logger.error( f"{res['errorMessages']}") else: log.logger.error( f"{res['errors']}") else: if res['fields']['status'][ 'name'] == 'Closed': k['status'] = 'Mitigated' # Sending emails subject = "Threat Model Security - Threat closed" body = f"{projectJiraKey} - {k['description']} was closed." mail.sendEmail( subject, body, receiver) if k['status'] != "Mitigated": print( json.dumps(res, sort_keys=True, indent=4, separators=(",", ": "))) print("") else: print("Has Threats: No") print('') print('') print('---------------') # Save the changes to JSON file JSON_file = open(threatJasonPath, 'w+') JSON_file.write(json.dumps(obj, indent=2)) JSON_file.close() else: log.logger.info(f'Start processing {threatJasonPath} ') log.logger.info( f'Missing Jira Key in the Threat Model diagram.') except Exception as e: log.logger.error("Exception occurred", exc_info=True) log.logger.info(f'Finish processing \n') mail.sendErrorEmail( "Threat Model: Exception occurred parsing the JSON file", e) raise e