def mutate(self, info, resource_data: Dict[str, Any], project_name: str, res_type: str) -> object: success = False user_email = util.get_jwt_content(info.context)['user_email'] add_res = resources.create_resource(resource_data, project_name, res_type, user_email) if add_res: resources.send_mail(project_name, user_email, resource_data, 'added', res_type) success = True else: rollbar.report_message('Error: \ An error occurred adding resource', 'error', info.context) if success: util.invalidate_cache(project_name) util.cloudwatch_log(info.context, 'Security: Added resources to \ {project} project succesfully'.format(project=project_name)) else: util.cloudwatch_log(info.context, 'Security: Attempted to add resources \ from {project} project'.format(project=project_name)) ret = AddResources(success=success, resources=Resource(project_name)) return ret
def verify_and_call(*args, **kwargs): context = args[1].context event_id = kwargs.get('event_id') \ if kwargs.get('identifier') is None else kwargs.get('identifier') user_data = util.get_jwt_content(context) user_data['subscribed_projects'] = \ user_domain.get_projects(user_data['user_email']) user_data['subscribed_projects'] += \ user_domain.get_projects(user_data['user_email'], active=False) user_data['role'] = get_user_role(user_data) event_project = event_domain.get_event(event_id).get('project_name') if not re.match('^[0-9]*$', event_id): rollbar.report_message('Error: Invalid event id format', 'error', context) raise GraphQLError('Invalid event id format') try: if not ENFORCER_BASIC.enforce(user_data, event_project.lower()): util.cloudwatch_log( context, 'Security: \ Attempted to retrieve event-related info without permission') raise GraphQLError('Access denied') except AttributeDoesNotExist: return GraphQLError('Access denied: Missing attributes') return func(*args, **kwargs)
def mutate(self, info, **parameters): success = False files_data = parameters['files_data'] uploaded_file = info.context.FILES['1'] project_name = parameters['project_name'] user_email = util.get_jwt_content(info.context)['user_email'] add_file = resources.create_file(files_data, uploaded_file, project_name, user_email) if add_file: resources.send_mail(project_name, user_email, files_data, 'added', 'file') success = True else: rollbar.report_message('Error: \ An error occurred uploading file', 'error', info.context) if success: util.invalidate_cache(project_name) util.cloudwatch_log(info.context, 'Security: Added evidence files to \ {project} project succesfully'.format(project=project_name)) else: util.cloudwatch_log(info.context, 'Security: Attempted to add evidence files \ from {project} project'.format(project=project_name)) ret = AddFiles(success=success, resources=Resource(project_name)) return ret
def mutate(self, info, **parameters): success = False file_info = parameters['files_data'] project_name = parameters['project_name'].lower() user_email = util.get_jwt_content(info.context)['user_email'] signed_url = resources.download_file(file_info, project_name) if signed_url: msg = 'Security: Downloaded file {file_name} in project {project} succesfully'\ .format(project=project_name, file_name=parameters['files_data']) util.cloudwatch_log(info.context, msg) mp_obj = Mixpanel(settings.MIXPANEL_API_TOKEN) mp_obj.track(user_email, 'DownloadProjectFile', { 'Project': project_name.upper(), 'Email': user_email, 'FileName': parameters['files_data'], }) success = True else: util.cloudwatch_log(info.context, 'Security: Attempted to download file {file_name} \ in project {project}'.format(project=project_name, file_name=parameters['files_data'])) rollbar.report_message('Error: \ An error occurred generating signed URL', 'error', info.context) ret = DownloadFile(success=success, url=str(signed_url)) return ret
def mutate(self, info, resource_data: Dict[str, Any], project_name: str, res_type: str) -> object: success = False user_email = util.get_jwt_content(info.context)['user_email'] update_res = resources.update_resource(resource_data, project_name, res_type, user_email) if update_res: resources.send_mail(project_name, user_email, [resource_data], 'activated' if resource_data.get('state') == 'INACTIVE' else 'deactivated', res_type) success = True else: rollbar.report_message('Error: \ An error occurred updating resource', 'error', info.context) if success: util.invalidate_cache(project_name) util.cloudwatch_log(info.context, 'Security: Updated resources from \ {project} project succesfully'.format(project=project_name)) else: util.cloudwatch_log(info.context, 'Security: Attempted to update resources \ from {project} project'.format(project=project_name)) ret = UpdateResources(success=success, resources=Resource(project_name)) return ret
def mutate(_, info, project_name: str, repo: Dict[str, str], state: str) -> object: user_email = util.get_jwt_content(info.context)['user_email'] success = resources.update_resource( repo, project_name, 'repository', user_email) if success: util.invalidate_cache(project_name) util.cloudwatch_log( info.context, f'Security: Updated repository state in {project_name} ' 'project succesfully') action = 'activated' if state == 'ACTIVE' else 'deactivated' resources.send_mail( project_name, user_email, [repo], action, 'repository') else: rollbar.report_message( 'An error occurred updating repository state', level='error', payload_data=locals()) util.cloudwatch_log( info.context, 'Security: Attempted to update repository state in ' f'{project_name} project') return UpdateRepository(success=success)
def mutate(self, info, **parameters): project_name = parameters.get('project_name').lower() user_info = util.get_jwt_content(info.context) current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') comment_id = int(round(time.time() * 1000)) comment_data = { 'user_id': comment_id, 'content': parameters.get('content'), 'created': current_time, 'fullname': str.join(' ', [user_info['first_name'], user_info['last_name']]), 'modified': current_time, 'parent': int(parameters.get('parent')) } success = project_domain.add_comment( project_name, user_info['user_email'], comment_data) if success: util.invalidate_cache(project_name) util.cloudwatch_log(info.context, 'Security: Added comment to \ {project} project succesfully'.format(project=project_name)) else: util.cloudwatch_log(info.context, 'Security: Attempted to add \ comment in {project} project'.format(project=project_name)) ret = AddProjectComment(success=success, comment_id=comment_id) return ret
def add_vuln_to_dynamo(item: Dict[str, str], specific: str, vuln: str, finding_id: str, info) -> bool: """Add vulnerability to dynamo.""" historic_state = [] last_finding_state = cast( List[Dict[str, str]], finding_dal.get_finding(finding_id)['historic_treatment'])[-1] where = item.get('where', '') vulnerability = cast( List[Dict[str, str]], vuln_dal.get(finding_id, vuln_type=vuln, where=where, specific=specific)) response = False tzn = pytz.timezone(settings.TIME_ZONE) # type: ignore current_day = datetime.now(tz=tzn).today().strftime('%Y-%m-%d %H:%M:%S') user_data = cast(UserType, util.get_jwt_content(info.context)) email = str(user_data['user_email']) if vulnerability: response = update_vuln_state(info, vulnerability, item, finding_id, current_day) else: data: Dict[str, FindingType] = {} data['vuln_type'] = vuln data['where'] = where data['specific'] = specific data['finding_id'] = finding_id data['UUID'] = str(uuid.uuid4()) data['treatment'] = 'NEW' if last_finding_state['treatment'] != 'NEW': data['treatment_manager'] = last_finding_state.get('user', '') if item.get('state'): if util.is_api_token(user_data): historic_state.append({ 'date': current_day, 'state': item.get('state', ''), 'origin': item.get('origin', ''), 'approval_status': 'PENDING', 'analyst': 'api-{email}'.format(email=email) }) else: historic_state.append({ 'date': current_day, 'state': item.get('state', ''), 'analyst': email }) data['historic_state'] = historic_state response = vuln_dal.create(data) else: util.cloudwatch_log( info.context, 'Security: Attempted to add vulnerability without state') return response
def resolve_authorized(self, info): """ Resolve user authorization """ jwt_content = util.get_jwt_content(info.context) user_email = jwt_content.get('user_email') self.authorized = user_domain.is_registered(user_email) return self.authorized
def verify_and_call(*args, **kwargs): context = args[1].context project_name = kwargs.get('project_name') user_data = util.get_jwt_content(context) user_data['subscribed_projects'] = \ user_domain.get_projects(user_data['user_email']) user_data['subscribed_projects'] += \ user_domain.get_projects(user_data['user_email'], active=False) user_data['role'] = get_user_role(user_data) if not project_name: rollbar.report_message('Error: Empty fields in project', 'error', context) raise GraphQLError('Access denied') try: if not ENFORCER_BASIC.enforce(user_data, project_name.lower()): util.cloudwatch_log( context, 'Security: \ Attempted to retrieve {project} project info without permission'.format( project=kwargs.get('project_name'))) raise GraphQLError('Access denied') util.cloudwatch_log( context, 'Security: Access to {project} project'.format( project=kwargs.get('project_name'))) except AttributeDoesNotExist: return GraphQLError('Access denied') return func(*args, **kwargs)
def export_users(request): user_data = util.get_jwt_content(request) book = Workbook() sheet = book.active sheet.append(['full_name', 'user_email']) row_index = 2 unique_users = [] for user in user_dal.get_platform_users(): user_email = user['user_email'].lower() if user_email not in unique_users: unique_users.append(user_email) name_attrs = user_domain.get_attributes( user_email, ['first_name', 'last_name']) full_name = ' '.join(list(name_attrs.values())) sheet.cell(row_index, 1, full_name) sheet.cell(row_index, 2, user_email) row_index += 1 username = user_data['user_email'].split('@')[0].encode('utf8', 'ignore') filepath = f'/tmp/{username}-users.xlsx' filename = os.path.basename(filepath) book.save(filepath) with open(filepath, 'rb') as document: response = HttpResponse(document.read()) response['Content-Type'] = 'application/vnd.openxmlformats\ -officedocument.spreadsheetml.sheet' response['Content-Disposition'] = f'inline;filename={filename}' return response
def resolve_comments(self, info): user_data = util.get_jwt_content(info.context) curr_user_role = get_user_role(user_data) self.comments = [ Comment(**comment) for comment in project_domain.list_comments( self.name, curr_user_role)] return self.comments
def resolve_remember(self, info): """ Resolve remember preference """ jwt_content = util.get_jwt_content(info.context) user_email = jwt_content.get('user_email') user_info = user_domain.get_data(user_email, 'legal_remember') self.remember = user_info if user_info else False return self.remember
def resolve_comments(self, info): """ Resolve comments attribute """ user_data = util.get_jwt_content(info.context) curr_user_role = get_user_role(user_data) self.comments = [ Comment(**comment) for comment in comment_domain.get_comments(self.id, curr_user_role) ] return self.comments
def resolve_observations(self, info): """ Resolve observations attribute """ user_data = util.get_jwt_content(info.context) curr_user_role = get_user_role(user_data) self.observations = [ Comment(**obs) for obs in comment_domain.get_observations(self.id, curr_user_role) ] return self.observations
def resolve_projects(self, info): jwt_content = util.get_jwt_content(info.context) user_email = jwt_content.get('user_email') for project in user_domain.get_projects(user_email): self.projects.append( Project(project_name=project, description=project_domain.get_description(project))) return self.projects
def mutate(self, info, finding_id): analyst_email = util.get_jwt_content(info.context)['user_email'] success = finding_domain.submit_draft(finding_id, analyst_email) if success: util.invalidate_cache(finding_id) util.cloudwatch_log( info.context, 'Security: Submitted draft ' '{} succesfully'.format(finding_id)) return SubmitDraft(success=success)
def resolve_role(self, info, project_name=None): jwt_content = util.get_jwt_content(info.context) role = get_user_role(jwt_content) if project_name and role == 'customer': email = jwt_content.get('user_email') role = 'customeradmin' if is_customeradmin(project_name, email) else 'customer' self.role = role return self.role
def mutate(self, info, project_name): user_info = util.get_jwt_content(info.context) success = project_domain.reject_deletion(project_name, user_info['user_email']) if success: project = project_name.lower() util.invalidate_cache(project) util.cloudwatch_log( info.context, f'Security: Reject project {project} deletion succesfully') return RejectRemoveProject(success=success)
def resolve_users(self, info): """ Resolve project users """ init_email_list = project_domain.get_users(self.name) user_email_list = util.user_email_filter( init_email_list, util.get_jwt_content(info.context)['user_email']) self.users = [User(self.name, user_email) for user_email in user_email_list if user_domain.get_data(user_email, 'role') in ['customer', 'customeradmin']] return self.users
def resolve_comments(self, info): """ Resolve comments attribute """ self.comments = [ Comment(**comment) for comment in comment_domain.get_event_comments( self.id, util.get_jwt_content(info.context)['user_role']) ] return self.comments
def create_draft(info, project_name: str, title: str, **kwargs) -> bool: last_fs_id = 550000000 finding_id = str(random.randint(last_fs_id, 1000000000)) tzn = pytz.timezone(settings.TIME_ZONE) # type: ignore project_name = project_name.lower() today = datetime.now(tz=tzn).today() creation_date = today.strftime('%Y-%m-%d %H:%M:%S') user_data = cast(UserType, util.get_jwt_content(info.context)) analyst_email = str(user_data.get('user_email', '')) submission_history = { 'analyst': analyst_email, 'date': creation_date, 'state': 'CREATED' } if util.is_api_token(user_data): submission_history.update({ 'analyst': f'api-{analyst_email}', 'origin': kwargs.get('origin', 'api') }) if 'description' in kwargs: kwargs['vulnerability'] = kwargs['description'] del kwargs['description'] if 'recommendation' in kwargs: kwargs['effect_solution'] = kwargs['recommendation'] del kwargs['recommendation'] if 'type' in kwargs: kwargs['finding_type'] = kwargs['type'] del kwargs['type'] finding_attrs = kwargs.copy() finding_attrs.update({ 'analyst': analyst_email, 'cvss_version': '3.1', 'exploitability': 0, 'files': [], 'finding': title, 'report_date': creation_date, 'historic_state': [submission_history], 'historic_treatment': [{ 'treatment': 'NEW', 'date': creation_date, 'user': analyst_email }] }) if re.search(r'^[A-Z]+\.(H\.|S\.|SH\.)??[0-9]+\. .+', title): return finding_dal.create(finding_id, project_name, finding_attrs) raise InvalidDraftTitle()
def resolve_create_event(_, info, project_name, image=None, file=None, **kwa): """Resolve create_event mutation.""" analyst_email = util.get_jwt_content(info.context)['user_email'] success = event_domain.create_event(analyst_email, project_name.lower(), file, image, **kwa) if success: util.cloudwatch_log( info.context, 'Security: Created event in ' f'{project_name} project succesfully') util.invalidate_cache(project_name) return dict(success=success)
def export_all_vulnerabilities(request): user_data = util.get_jwt_content(request) filepath = generate_all_vulns_xlsx(user_data['user_email']) filename = os.path.basename(filepath) with open(filepath, 'rb') as document: response = HttpResponse(document.read()) response['Content-Type'] = 'application/vnd.openxmlformats\ -officedocument.spreadsheetml.sheet' response['Content-Disposition'] = 'inline;filename={filename}'.format( filename=filename) return response
def mutate(_, info, remember): user_email = util.get_jwt_content(info.context)['user_email'] is_registered = user_domain.is_registered(user_email) if is_registered: user_domain.update_legal_remember(user_email, remember) success = True else: success = False return AcceptLegal(success=success)
def resolve_accept_legal(_, info, remember=False): """Resolve accept_legal mutation.""" user_email = util.get_jwt_content(info.context)['user_email'] is_registered = user_domain.is_registered(user_email) if is_registered: user_domain.update_legal_remember(user_email, remember) success = True else: success = False return dict(success=success)
def verify_and_call(*args, **kwargs): context = args[1].context try: user_data = util.get_jwt_content(context) if user_data.get('jti'): verify_jti(user_data['user_email'], context.META.get('HTTP_AUTHORIZATION'), user_data['jti']) except InvalidAuthorization: raise GraphQLError('Login required') return func(*args, **kwargs)
def mutate(self, info, **kwargs): user_data = util.get_jwt_content(info.context) user_role = get_user_role(user_data) success = project_domain.create_project( user_data['user_email'], user_role, **kwargs) if success: project = kwargs.get('project_name').lower() util.invalidate_cache(user_data['user_email']) util.cloudwatch_log( info.context, f'Security: Created project {project} succesfully') return CreateProject(success=success)
def resolve_project(self, info, project_name): """Resolve for projects.""" project_name = project_name.lower() user_email = util.get_jwt_content(info.context)['user_email'] if project_domain.is_request_deletion_user(project_name, user_email): util.cloudwatch_log( info.context, f'Security: Access to project {project_name} succesfully') return Project( project_name, description=project_domain.get_description(project_name)) raise InvalidProject()
def resolve_access_token(self, info): jwt_content = util.get_jwt_content(info.context) user_email = jwt_content.get('user_email') access_token = user_domain.get_data(user_email, 'access_token') access_token_dict = { 'hasAccessToken': bool(access_token), 'issuedAt': str(access_token.get('iat', '')) if bool(access_token) else '' } self.access_token = json.dumps(access_token_dict) return self.access_token