def verify_and_call(*args, **kwargs):
        context = args[1].context
        finding_id = kwargs.get('finding_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)
        finding_project = finding_domain.get_finding(finding_id).get(
            'projectName')

        if not re.match('^[0-9]*$', finding_id):
            rollbar.report_message('Error: Invalid finding id format', 'error',
                                   context)
            raise GraphQLError('Invalid finding id format')
        try:
            if not ENFORCER_BASIC.enforce(user_data, finding_project.lower()):
                util.cloudwatch_log(
                    context, 'Security: \
    Attempted to retrieve finding-related info without permission')
                raise GraphQLError('Access denied')
        except AttributeDoesNotExist:
            return GraphQLError('Access denied')
        return func(*args, **kwargs)
 def mutate(self, info, finding_id, **parameters):
     project_name = finding_domain.get_finding(finding_id)['projectName']
     user_mail = util.get_jwt_content(info.context)['user_email']
     if parameters.get('acceptance_status') == '':
         del parameters['acceptance_status']
     historic_treatment = finding_domain.get_finding(
         finding_id)['historicTreatment']
     last_state = {
         key: value
         for key, value in historic_treatment[-1].items()
         if key not in ['date', 'user']
     }
     new_state = {
         key: value
         for key, value in parameters.items() if key != 'bts_url'
     }
     bts_changed, treatment_changed = True, True
     Status = namedtuple('Status', 'bts_changed treatment_changed')
     if not finding_domain.compare_historic_treatments(
             last_state, new_state):
         treatment_changed = False
     if ('externalBts' in finding_domain.get_finding(finding_id)
             and parameters.get('bts_url')
             == finding_domain.get_finding(finding_id)['externalBts']):
         bts_changed = False
     update = Status(bts_changed=bts_changed,
                     treatment_changed=treatment_changed)
     if not any(list(update)):
         raise GraphQLError(
             'It cant be updated a finding with same values it already has')
     success = finding_domain.update_client_description(
         finding_id, parameters, user_mail, update)
     if success:
         util.invalidate_cache(finding_id)
         util.invalidate_cache(project_name)
         util.cloudwatch_log(
             info.context, 'Security: Updated treatment in '
             f'finding {finding_id} succesfully')
         util.forces_trigger_deployment(project_name)
     else:
         util.cloudwatch_log(
             info.context, 'Security: Attempted to update '
             f'treatment in finding {finding_id}')
     findings_loader = info.context.loaders['finding']
     return UpdateClientDescription(
         finding=findings_loader.load(finding_id), success=success)
def has_access_to_finding(user: str, finding_id: str, role: str) -> bool:
    """ Verify if the user has access to a finding submission. """
    has_access = False
    # Skip this check for admin users since they don't have any assigned projects
    if role == 'admin':
        has_access = True
    else:
        finding = finding_domain.get_finding(finding_id)
        has_access = has_access_to_project(user,
                                           str(finding.get('projectName', '')),
                                           role)

    return has_access
示例#4
0
 def test_delete_finding(self):
     query = '''
       mutation {
         deleteFinding(findingId: "560175507", justification: NOT_REQUIRED) {
           success
         }
       }
     '''
     testing_client = Client(SCHEMA)
     request_loaders = {'finding': FindingLoader()}
     result = self._get_result(query, testing_client, request_loaders)
     assert 'errors' not in result
     assert result['data']['deleteFinding']['success']
     with pytest.raises(FindingNotFound):
         assert get_finding('560175507')
def format_release_date(finding):
    finding_dynamo = finding_domain.get_finding(finding['findingId'])
    if finding_dynamo:
        if finding_dynamo[0].get("releaseDate"):
            finding["releaseDate"] = finding_dynamo[0].get("releaseDate")
        if finding_dynamo[0].get("lastVulnerability"):
            finding["lastVulnerability"] = \
                finding_dynamo[0].get("lastVulnerability")
    if finding.get("releaseDate"):
        final_date = util.calculate_datediff_since(finding["releaseDate"])
        finding['edad'] = final_date.days
        final_vuln_date = util.calculate_datediff_since(finding["lastVulnerability"])
        finding['lastVulnerability'] = final_vuln_date.days
    else:
        finding['lastVulnerability'] = '-'
    return finding
    def mutate(self, info, finding_id, justification):
        project_name = finding_domain.get_finding(finding_id)['projectName']

        success = finding_domain.delete_finding(finding_id, project_name,
                                                justification, info.context)
        if success:
            util.invalidate_cache(finding_id)
            util.invalidate_cache(project_name)
            util.cloudwatch_log(
                info.context,
                f'Security: Deleted finding: {finding_id} succesfully')
        else:
            util.cloudwatch_log(
                info.context,
                f'Security: Attempted to delete finding: {finding_id}')
        return DeleteFinding(success=success)
    def mutate(self, info, finding_id):
        reviewer_email = util.get_jwt_content(info.context)['user_email']
        project_name = finding_domain.get_finding(finding_id)['projectName']

        success = finding_domain.reject_draft(finding_id, reviewer_email)
        if success:
            util.invalidate_cache(finding_id)
            util.invalidate_cache(project_name)
            util.cloudwatch_log(
                info.context,
                'Security: Draft {} rejected succesfully'.format(finding_id))
        else:
            util.cloudwatch_log(
                info.context,
                'Security: Attempted to reject draft {}'.format(finding_id))
        return RejectDraft(success=success)
 def mutate(self, info, finding_id, **parameters):
     success = finding_domain.update_description(finding_id, parameters)
     if success:
         project_name = finding_domain.get_finding(
             finding_id)['projectName']
         util.invalidate_cache(finding_id)
         util.invalidate_cache(project_name)
         util.cloudwatch_log(
             info.context, 'Security: Updated description in\
             finding {id} succesfully'.format(id=finding_id))
     else:
         util.cloudwatch_log(
             info.context, 'Security: Attempted to update \
             description in finding {id}'.format(id=finding_id))
     findings_loader = info.context.loaders['finding']
     ret = UpdateDescription(finding=findings_loader.load(finding_id),
                             success=success)
     return ret
 def mutate(self, info, **parameters):
     """update vulnerabilities in database."""
     min_value = 0
     max_value = 1000000000
     vulnerabilities = parameters.get('vulnerabilities')
     finding_id = parameters.get('finding_id')
     if parameters.get('severity') and parameters.get('severity') != -1:
         if min_value > parameters.get('severity') or \
            parameters.get('severity') > max_value:
             raise InvalidSeverity([min_value, max_value])
     user_data = util.get_jwt_content(info.context)
     project_name = finding_domain.get_finding(finding_id)['projectName']
     is_customer_admin = is_customeradmin(project_name,
                                          user_data['user_email'])
     result_update_vuln = update_treatments(vulnerabilities, finding_id,
                                            parameters, info,
                                            is_customer_admin)
     if result_update_vuln:
         util.invalidate_cache(finding_id)
     result = UpdateTreatmentVuln(success=result_update_vuln)
     return result
    def mutate(self, info, **parameters):
        user_info = util.get_jwt_content(info.context)
        user_mail = user_info['user_email']
        finding_id = parameters.get('finding_id')
        historic_treatment = finding_domain.get_finding(finding_id).get(
            'historicTreatment')
        if historic_treatment[-1]['acceptance_status'] != 'SUBMITTED':
            raise GraphQLError('It cant be approved/rejected a finding' +
                               'definite assumption without being requested')

        success = finding_domain.handle_acceptation(
            finding_id, parameters.get('observations'), user_mail,
            parameters.get('response'))
        if success:
            util.invalidate_cache(finding_id)
            util.invalidate_cache(parameters.get('project_name'))
            util.cloudwatch_log(
                info.context, 'Security: Verified a request '
                f'in finding_id: {finding_id}')
        ret = HandleAcceptation(success=success)
        return ret
    def mutate(self, info, draft_id):
        reviewer_email = util.get_jwt_content(info.context)['user_email']
        project_name = finding_domain.get_finding(draft_id)['projectName']

        has_vulns = [
            vuln for vuln in vuln_domain.list_vulnerabilities([draft_id])
            if vuln['historic_state'][-1].get('state') != 'DELETED'
        ]
        if not has_vulns:
            raise GraphQLError('CANT_APPROVE_FINDING_WITHOUT_VULNS')
        success, release_date = finding_domain.approve_draft(
            draft_id, reviewer_email)
        if success:
            util.invalidate_cache(draft_id)
            util.invalidate_cache(project_name)
            util.cloudwatch_log(
                info.context, 'Security: Approved draft in\
                {project} project succesfully'.format(project=project_name))
        else:
            util.cloudwatch_log(
                info.context, 'Security: Attempted to approve \
                draft in {project} project'.format(project=project_name))
        return ApproveDraft(release_date, success)
def download_vulnerabilities(request, findingid):
    """Download a file with all the vulnerabilities."""
    if not has_access_to_finding(request.session['username'], findingid,
                                 request.session['role']):
        util.cloudwatch_log(request,
                            'Security: \
Attempted to retrieve vulnerabilities without permission')
        return util.response([], 'Access denied', True)
    else:
        finding = get_vulnerabilities_by_type(findingid)
        data_yml = {}
        vuln_types = {'ports': dict, 'lines': dict, 'inputs': dict}
        if finding:
            for vuln_key, cast_fuction in list(vuln_types.items()):
                if finding.get(vuln_key):
                    data_yml[vuln_key] = list(map(cast_fuction, list(finding.get(vuln_key))))
                else:
                    # This finding does not have this type of vulnerabilities
                    pass
        else:
            # This finding does not have new vulnerabilities
            pass
        project = finding_domain.get_finding(findingid)['projectName']
        file_name = '/tmp/{project}-{finding_id}.yaml'.format(
            finding_id=findingid, project=project)
        stream = open(file_name, 'w')
        yaml.safe_dump(data_yml, stream, default_flow_style=False)
        try:
            with open(file_name, 'rb') as file_obj:
                response = HttpResponse(file_obj.read(), content_type='text/x-yaml')
                response['Content-Disposition'] = \
                    'attachment; filename="{project}-{finding_id}.yaml"'.format(
                        finding_id=findingid, project=project)
                return response
        except IOError:
            rollbar.report_message('Error: Invalid vulnerabilities file format', 'error', request)
            return util.response([], 'Invalid vulnerabilities file format', True)