def reject_deletion(project_name: str, user_email: str) -> bool:
    response = False
    project = project_name.lower()
    if is_request_deletion_user(project,
                                user_email) and project_name == project:
        data = project_dal.get_attributes(
            project, ['project_status', 'historic_deletion'])
        historic_deletion = cast(List[Dict[str, str]],
                                 data.get('historic_deletion', []))
        if data.get('project_status') == 'PENDING_DELETION':
            tzn = pytz.timezone(settings.TIME_ZONE)  # type: ignore
            today = datetime.now(tz=tzn).today()
            new_state = {
                'date': today.strftime('%Y-%m-%d %H:%M:%S'),
                'user': user_email.lower(),
                'state': 'REJECTED'
            }
            historic_deletion.append(new_state)
            new_data = {
                'project_status': 'ACTIVE',
                'historic_deletion': historic_deletion
            }
            response = project_dal.update(project, new_data)
        else:
            raise NotPendingDeletion()
    else:
        raise PermissionDenied()
    return response
def request_deletion(project_name: str, user_email: str) -> bool:
    project = project_name.lower()
    response = False
    if user_domain.get_project_access(user_email,
                                      project) and project_name == project:
        data = project_dal.get_attributes(
            project, ['project_status', 'historic_deletion'])
        historic_deletion = cast(List[Dict[str, str]],
                                 data.get('historic_deletion', []))
        if data.get('project_status') not in ['DELETED', 'PENDING_DELETION']:
            tzn = pytz.timezone(settings.TIME_ZONE)  # type: ignore
            today = datetime.now(tz=tzn).today()
            deletion_date = (
                today + timedelta(days=30)).strftime('%Y-%m-%d') + ' 23:59:59'
            new_state = {
                'date': today.strftime('%Y-%m-%d %H:%M:%S'),
                'deletion_date': deletion_date,
                'user': user_email.lower(),
            }
            historic_deletion.append(new_state)
            new_data: ProjectType = {
                'historic_deletion': historic_deletion,
                'project_status': 'PENDING_DELETION'
            }
            response = project_dal.update(project, new_data)
        else:
            raise AlreadyPendingDeletion()
    else:
        raise PermissionDenied()
    return response
Esempio n. 3
0
def has_repeated_envs(project_name: str, envs: List[Dict[str, str]]) -> bool:
    unique_inputs = list({env['urlEnv']: env for env in envs}.values())
    has_repeated_inputs = len(envs) != len(unique_inputs)

    existing_envs = cast(
        List[Dict[str, str]],
        project_dal.get_attributes(project_name.lower(),
                                   ['environments']).get('environments', []))
    all_envs = [{'urlEnv': env['urlEnv']} for env in existing_envs] + envs

    unique_envs = list({env['urlEnv']: env for env in all_envs}.values())
    has_repeated_existing = len(all_envs) != len(unique_envs)

    return has_repeated_inputs or has_repeated_existing
Esempio n. 4
0
def create_file(files_data: List[Dict[str, str]], uploaded_file,
                project_name: str, user_email: str) -> bool:
    validations.validate_field(cast(List[str], files_data[0]['description']))
    project_name = project_name.lower()
    json_data: List[resources_dal.ResourceType] = []
    for file_info in files_data:
        json_data.append({
            'fileName':
            file_info.get('fileName', ''),
            'description':
            file_info.get('description', ''),
            'uploadDate':
            str(datetime.now().replace(second=0, microsecond=0))[:-3],
            'uploader':
            user_email,
        })
    file_id = '{project}/{file_name}'.format(project=project_name,
                                             file_name=uploaded_file)
    try:
        file_size = 100
        validate_file_size(uploaded_file, file_size)
    except InvalidFileSize:
        rollbar.report_message('Error: \
File exceeds size limit', 'error')
    files = project_dal.get_attributes(project_name, ['files'])
    project_files = cast(List[Dict[str, str]], files.get('files'))
    if project_files:
        contains_repeated = [
            f.get('fileName') for f in project_files
            if f.get('fileName') == uploaded_file.name
        ]
        if contains_repeated:
            rollbar.report_message('Error: \
File already exists', 'error')
    else:
        # Project doesn't have files
        pass
    if util.is_valid_file_name(uploaded_file):
        return (resources_dal.save_file(uploaded_file, file_id)
                and resources_dal.create(json_data, project_name, 'files'))
    return False
Esempio n. 5
0
def has_repeated_repos(project_name: str, repos: List[Dict[str, str]]) -> bool:
    unique_inputs = list({(repo['urlRepo'], repo['branch'],
                           repo.get('protocol', '')): repo
                          for repo in repos}.values())
    has_repeated_inputs = len(repos) != len(unique_inputs)

    existing_repos = cast(
        List[Dict[str, str]],
        project_dal.get_attributes(project_name.lower(),
                                   ['repositories']).get('repositories', []))
    all_repos = [{
        'urlRepo': repo['urlRepo'],
        'branch': repo['branch'],
        'protocol': repo.get('protocol', '')
    } for repo in existing_repos] + repos

    unique_repos = list({(repo['urlRepo'], repo['branch'],
                          repo.get('protocol')): repo
                         for repo in all_repos}.values())
    has_repeated_existing = len(all_repos) != len(unique_repos)

    return has_repeated_inputs or has_repeated_existing
Esempio n. 6
0
def mask(project_name: str) -> NamedTuple:
    project_name = project_name.lower()
    project = project_dal.get_attributes(
        project_name, ['environments', 'files', 'repositories'])
    Status: NamedTuple = namedtuple(
        'Status',
        'are_files_removed files_result environments_result repositories_result'
    )
    are_files_removed = all([
        resources_dal.remove_file(file_name)
        for file_name in resources_dal.search_file(f'{project_name}/')
    ])
    files_result = project_dal.update(
        project_name, {
            'files': [{
                'fileName': 'Masked',
                'description': 'Masked',
                'uploader': 'Masked'
            } for file_resource in project.get('files', [])]
        })
    environments_result = project_dal.update(
        project_name, {
            'environments': [{
                'urlEnv': 'Masked'
            } for file_resource in project.get('environments', [])]
        })
    repositories_result = project_dal.update(
        project_name, {
            'repositories': [{
                'protocol': 'Masked',
                'urlRepo': 'Masked'
            } for file_resource in project.get('repositories', [])]
        })
    success = cast(
        NamedTuple,
        Status(are_files_removed, files_result, environments_result,
               repositories_result))
    return success
def remove_project(project_name: str, user_email: str) -> NamedTuple:
    """Delete project information."""
    project = project_name.lower()
    Status: NamedTuple = namedtuple(
        'Status',
        'are_findings_masked are_users_removed is_project_finished are_resources_removed'
    )
    response = Status(False, False, False, False)
    data = project_dal.get_attributes(project, ['project_status'])
    validation = False
    if user_email:
        validation = is_alive(project) and user_domain.get_project_access(
            user_email, project)
    if (not user_email and data.get('project_status')
            == 'PENDING_DELETION') or validation:
        tzn = pytz.timezone(settings.TIME_ZONE)  # type: ignore
        today = datetime.now(tz=tzn).today().strftime('%Y-%m-%d %H:%M:%S')
        are_users_removed = remove_all_users_access(project)
        are_findings_masked: Union[bool, List[bool]] = [
            finding_domain.mask_finding(finding_id)
            for finding_id in list_findings(project) + list_drafts(project)
        ]
        if are_findings_masked == []:
            are_findings_masked = True
        update_data: Dict[str, Union[str, List[str], object]] = {
            'project_status': 'FINISHED',
            'deletion_date': today
        }
        is_project_finished = project_dal.update(project, update_data)
        are_resources_removed = all(
            list(cast(List[bool], resources_domain.mask(project))))
        util.invalidate_cache(project)
        response = Status(are_findings_masked, are_users_removed,
                          is_project_finished, are_resources_removed)
    else:
        raise PermissionDenied()
    return cast(NamedTuple, response)
def create_event(analyst_email: str,
                 project_name: str,
                 file=None,
                 image=None,
                 **kwargs) -> bool:
    validations.validate_field(kwargs['detail'])
    event_id = str(random.randint(10000000, 170000000))

    tzn = pytz.timezone(settings.TIME_ZONE)  # type: ignore
    today = datetime.now(tz=tzn).today()

    project = project_dal.get_attributes(project_name, ['companies', 'type'])
    subscription = str(project.get('type'))

    event_attrs = kwargs.copy()
    event_date = event_attrs['event_date'].astimezone(tzn).replace(tzinfo=None)
    del event_attrs['event_date']
    if event_date > today:
        raise InvalidDate()

    event_attrs.update({
        'accessibility':
        ' '.join(list(set(event_attrs['accessibility']))),
        'analyst':
        analyst_email,
        'client':
        project.get('companies', [''])[0],
        'historic_state': [{
            'analyst': analyst_email,
            'date': event_date.strftime('%Y-%m-%d %H:%M:%S'),
            'state': 'OPEN'
        }, {
            'analyst': analyst_email,
            'date': today.strftime('%Y-%m-%d %H:%M:%S'),
            'state': 'CREATED'
        }],
        'subscription':
        subscription.upper()
    })
    if 'affected_components' in event_attrs:
        event_attrs['affected_components'] = '\n'.join(
            list(set(event_attrs['affected_components'])))

    if any([file, image]):
        if file and image:
            valid = validate_evidence('evidence_file', file) \
                and validate_evidence('evidence', image)
        elif file:
            valid = validate_evidence('evidence_file', file)
        elif image:
            valid = validate_evidence('evidence', image)

        if valid and event_dal.create(event_id, project_name, event_attrs):
            if file:
                update_evidence(event_id, 'evidence_file', file)
            if image:
                update_evidence(event_id, 'evidence', image)
            success = True
            _send_new_event_mail(analyst_email, event_id, project_name,
                                 subscription, event_attrs['event_type'])

    else:
        success = event_dal.create(event_id, project_name, event_attrs)
        _send_new_event_mail(analyst_email, event_id, project_name,
                             subscription, event_attrs['event_type'])

    return success
def get_attributes(project_name: str,
                   attributes: List[str]) -> Dict[str, Union[str, List[str]]]:
    return project_dal.get_attributes(project_name, attributes)
def get_historic_deletion(project_name: str) -> Union[str, List[str]]:
    historic_deletion = project_dal.get_attributes(project_name.lower(),
                                                   ['historic_deletion'])
    return historic_deletion.get('historic_deletion', [])