Пример #1
0
    def test_does_not_sign_non_hawk_requests(self):
        """Test that a 403 is returned if the request is not authenticated using Hawk."""
        from rest_framework.test import force_authenticate

        factory = APIRequestFactory()
        user = create_test_user()
        view = HawkViewWithScope.as_view()

        request = factory.get('/test-hawk-with-scope/')
        force_authenticate(request, user=user)
        response = view(request)

        assert response.status_code == status.HTTP_403_FORBIDDEN
        assert response.data == {
            'detail': 'You do not have permission to perform this action.',
        }
Пример #2
0
    def test_document_upload_status_no_status_without_permission(self):
        """Tests user without permission can't call upload status endpoint."""
        entity_document = create_evidence_document()

        url = reverse(
            'api-v3:investment:evidence-document:document-item-callback',
            kwargs={
                'project_pk': entity_document.investment_project.pk,
                'entity_document_pk': entity_document.pk,
            },
        )

        user = create_test_user(permission_codenames=[], dit_team=TeamFactory())
        api_client = self.create_api_client(user=user)
        response = api_client.post(url, data={})
        assert response.status_code == status.HTTP_403_FORBIDDEN
Пример #3
0
    def test_permission_checking(self, permission_codenames, expected_status,
                                 api_client):
        """Test that the expected status is returned for various user permissions."""
        user = create_test_user(permission_codenames=permission_codenames,
                                dit_team=None)
        company_list = CompanyListFactory(adviser=user)
        url = _get_list_detail_url(company_list.pk)

        api_client = self.create_api_client(user=user)
        response = api_client.patch(
            url,
            data={
                'name': 'test list',
            },
        )
        assert response.status_code == expected_status
    def test_delete_company_export_countries_check_history_tracks_correct_user(
            self):
        """
        Check that history correctly tracks the user who deletes the export country
        """
        company = CompanyFactory()
        country = CountryModel.objects.order_by('name')[0]
        adviser = AdviserFactory()
        export_country = CompanyExportCountryFactory(
            company=company,
            country=country,
            status=CompanyExportCountry.Status.FUTURE_INTEREST,
            created_by=adviser,
        )
        CompanyExportCountryHistoryFactory(
            id=export_country.id,
            company=export_country.company,
            country=export_country.country,
            status=export_country.status,
            history_type=CompanyExportCountryHistory.HistoryType.INSERT,
            history_user=export_country.created_by,
        )

        new_user = create_test_user(permission_codenames=(
            'change_company',
            'change_companyexportcountry',
        ), )
        api_client = self.create_api_client(user=new_user)
        url = reverse('api-v4:company:update-export-detail',
                      kwargs={'pk': company.pk})
        response = api_client.patch(
            url,
            data={
                'export_countries': [],
            },
        )
        assert response.status_code == status.HTTP_204_NO_CONTENT

        company.refresh_from_db()
        assert company.export_countries.count() == 0
        delete_history = CompanyExportCountryHistory.objects.filter(
            company=company,
            history_type=CompanyExportCountryHistory.HistoryType.DELETE,
        )
        assert delete_history.count() == 1
        assert delete_history[0].country == country
        assert delete_history[0].history_user == new_user
Пример #5
0
 def test_user_without_permission_cannot_get_report(self):
     """Test that user without permission cannot get a report."""
     report = SPIReportFactory()
     url = reverse(
         'investment-report:download-spi-report',
         kwargs={
             'pk': report.pk,
         },
     )
     user = create_test_user(
         is_staff=True,
         password=self.PASSWORD,
         permission_codenames=(),
     )
     client = self.create_client(user=user)
     response = client.get(url)
     assert response.status_code == status.HTTP_403_FORBIDDEN
Пример #6
0
    def test_permission_denied_if_staff_and_without_change_permission(self):
        """
        Test that the view returns a 403 response if the staff user does not have the
        change contact permission.
        """
        url = reverse(
            admin_urlname(Contact._meta, 'load-email-marketing-opt-outs'),
        )
        user = create_test_user(
            permission_codenames=(ContactPermission.view_contact,),
            is_staff=True,
            password=self.PASSWORD,
        )

        client = self.create_client(user=user)
        response = client.get(url)
        assert response.status_code == status.HTTP_403_FORBIDDEN
Пример #7
0
    def test_view_returns_403(self):
        """
        Tests view returns 403
        """
        user = create_test_user(dit_team=TeamFactory())
        token = self.get_token(user=user)

        request = factory.get(
            '/',
            data={},
            content_type='application/json',
            Authorization=f'Bearer {token}',
        )
        my_view = PermissionModelViewset.as_view(actions={'get': 'list'}, )
        response = my_view(request)

        assert response.status_code == status.HTTP_403_FORBIDDEN
Пример #8
0
    def test_restricted_users_cannot_see_other_teams_projects(self, setup_es):
        """Test that restricted users cannot see other teams' projects in the export."""
        team = TeamFactory()
        team_other = TeamFactory()
        adviser_other = AdviserFactory(dit_team_id=team_other.id)
        adviser_same_team = AdviserFactory(dit_team_id=team.id)
        request_user = create_test_user(
            permission_codenames=(
                InvestmentProjectPermission.view_associated,
                InvestmentProjectPermission.export,
            ),
            dit_team=team,
        )
        api_client = self.create_api_client(user=request_user)

        project_other = InvestmentProjectFactory()
        team_projects = [
            InvestmentProjectFactory(),
            InvestmentProjectFactory(created_by=adviser_same_team),
            InvestmentProjectFactory(client_relationship_manager=adviser_same_team),
            InvestmentProjectFactory(project_manager=adviser_same_team),
            InvestmentProjectFactory(project_assurance_adviser=adviser_same_team),
        ]

        InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other)
        InvestmentProjectTeamMemberFactory(
            adviser=adviser_same_team,
            investment_project=team_projects[0],
        )

        setup_es.indices.refresh()

        url = reverse('api-v3:search:investment_project-export')
        response = api_client.post(url, {})

        assert response.status_code == status.HTTP_200_OK

        response_text = response.getvalue().decode('utf-8-sig')
        reader = DictReader(StringIO(response_text))
        actual_rows = [dict(item) for item in reader]

        assert len(actual_rows) == 5

        expected_names = {project.name for project in team_projects}

        assert {row['Project name'] for row in actual_rows} == expected_names
Пример #9
0
    def test_global_restricted_users_cannot_see_other_teams_projects(self, setup_es):
        """
        Automatic filter to see only associated IP for a specific (leps) user
        """
        team = TeamFactory()
        team_other = TeamFactory()
        adviser_other = AdviserFactory(dit_team_id=team_other.id)
        adviser_same_team = AdviserFactory(dit_team_id=team.id)
        request_user = create_test_user(
            permission_codenames=['view_associated_investmentproject'],
            dit_team=team,
        )
        api_client = self.create_api_client(user=request_user)

        project_other = InvestmentProjectFactory()
        project_1 = InvestmentProjectFactory()
        project_2 = InvestmentProjectFactory(created_by=adviser_same_team)
        project_3 = InvestmentProjectFactory(client_relationship_manager=adviser_same_team)
        project_4 = InvestmentProjectFactory(project_manager=adviser_same_team)
        project_5 = InvestmentProjectFactory(project_assurance_adviser=adviser_same_team)

        InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other)
        InvestmentProjectTeamMemberFactory(adviser=adviser_same_team, investment_project=project_1)

        setup_es.indices.refresh()

        url = reverse('api-v3:search:basic')
        response = api_client.get(
            url,
            data={
                'term': '',
                'entity': 'investment_project',
            },
        )

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['count'] == 5

        results = response_data['results']
        expected_ids = {
            str(project_1.id), str(project_2.id), str(project_3.id),
            str(project_4.id), str(project_5.id),
        }

        assert {result['id'] for result in results} == expected_ids
Пример #10
0
    def test_adviser_report_download(self):
        """Test the download of a report."""
        AdviserFactory.create_batch(5)

        url = reverse('admin_report:download-report', kwargs={'report_id': 'all-advisers'})

        user = create_test_user(
            permission_codenames=('view_advisor',),
            is_staff=True,
            password=self.PASSWORD,
        )

        client = self.create_client(user=user)
        response = client.get(url)
        assert response.status_code == status.HTTP_200_OK
        # 7 = header + test user + the 5 test advisers
        assert len(response.getvalue().decode('utf-8').splitlines()) == 7
    def test_restricted_user_cannot_update_company_interaction(self):
        """Test that a restricted user cannot update a company interaction."""
        requester = create_test_user(
            permission_codenames=[InteractionPermission.change_associated_investmentproject],
        )
        interaction = CompanyInteractionFactory(subject='I am a subject')

        api_client = self.create_api_client(user=requester)
        url = reverse('api-v3:interaction:item', kwargs={'pk': interaction.pk})
        response = api_client.patch(
            url,
            data={
                'subject': 'I am another subject',
            },
        )

        assert response.status_code == status.HTTP_403_FORBIDDEN
Пример #12
0
    def test_import_link_does_not_exist_if_only_has_view_permission(self):
        """
        Test that there is not a link to import interactions if the user only has the delete
        (but not change) permission for interactions.
        """
        user = create_test_user(
            permission_codenames=(InteractionPermission.view_all, ),
            is_staff=True,
            password=self.PASSWORD,
        )

        client = self.create_client(user=user)
        response = client.get(interaction_change_list_url)
        assert response.status_code == status.HTTP_200_OK

        assert f'Select {Interaction._meta.verbose_name} to view' in response.rendered_content
        assert import_interactions_url not in response.rendered_content
Пример #13
0
    def test_document_delete_without_permission(self, delete_document):
        """Tests user can't delete document without permissions."""
        entity_document = create_evidence_document()
        entity_document.document.mark_scan_scheduled()
        entity_document.document.mark_as_scanned(True, 'reason')

        url = reverse(
            'api-v3:investment:evidence-document:document-item',
            kwargs={
                'project_pk': entity_document.investment_project.pk,
                'entity_document_pk': entity_document.pk,
            },
        )
        user = create_test_user(permission_codenames=[], dit_team=TeamFactory())
        api_client = self.create_api_client(user=user)
        response = api_client.delete(url)
        assert response.status_code == status.HTTP_403_FORBIDDEN
        assert delete_document.called is False
Пример #14
0
 def test_non_restricted_user_cannot_get_non_existent_report(self):
     """Test user cannot get a report that doesn't exist."""
     url = reverse(
         'investment-report:download-spi-report',
         kwargs={
             'pk': uuid4(),
         },
     )
     user = create_test_user(
         is_staff=True,
         password=self.PASSWORD,
         permission_codenames=(
             SPIReportPermission.view,
         ),
     )
     client = self.create_client(user=user)
     response = client.get(url)
     assert response.status_code == status.HTTP_404_NOT_FOUND
Пример #15
0
    def test_add(self, permissions):
        """Test add a new interaction."""
        adviser = create_test_user(
            permission_codenames=permissions,
            dit_team=TeamFactory(),
        )
        contact = ContactFactory()
        communication_channel = random_obj_for_model(CommunicationChannel)
        service = Service.objects.get(
            pk=ServiceConstant.providing_investment_advice_and_information.
            value.id, )

        url = reverse('api-v3:interaction:collection')
        request_data = {
            'kind': Interaction.KINDS.interaction,
            'communication_channel': communication_channel.pk,
            'subject': 'whatever',
            'date': date.today().isoformat(),
            'dit_participants': [{
                'adviser': adviser.pk,
            }],
            'company': contact.company.pk,
            'contacts': [contact.pk],
            'was_policy_feedback_provided': False,
            'export_countries': [],
            'service': service.pk,
            'service_answers': {
                ServiceQuestionID.piai_what_did_you_give_advice_about.value: {
                    ServiceAnswerOptionID.piai_banking_and_funding.value: {},
                },
            },
        }

        api_client = self.create_api_client(user=adviser)
        response = api_client.post(url, request_data)
        assert response.status_code == status.HTTP_201_CREATED
        response_data = response.json()

        assert response_data['service'] == {
            'id': str(service.id),
            'name': service.name,
        }
        assert response_data['service_answers'] == request_data[
            'service_answers']
Пример #16
0
    def test_filter_by_permission(
        self,
        permission_config,
        filter_by_permission,
        should_match,
    ):
        """Test the `has_permission` filter in various cases."""
        user = create_test_user(
            permission_codenames=('view_advisor', ),
            is_superuser=permission_config.is_superuser,
            dit_team=TeamFactory(),
        )

        if permission_config.user_permission:
            permission = _get_permission(permission_config.user_permission)
            user.user_permissions.add(permission)

        if permission_config.group_permission:
            group = _make_group('group 1', permission_config.group_permission)
            user.groups.add(group)

        if permission_config.team_role_permission:
            group = _make_group('group 2',
                                permission_config.team_role_permission)
            user.dit_team.role.groups.add(group)

        api_client = self.create_api_client(user=user)

        url = reverse('api-v1:advisor-list')
        response = api_client.get(
            url,
            data={
                'permissions__has': filter_by_permission,
            },
        )
        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()

        if should_match:
            assert response_data['count'] == 1
            result = response_data['results'][0]
            assert result['id'] == str(user.pk)
        else:
            assert response_data['count'] == 0
Пример #17
0
    def test_403_if_no_permissions(self):
        """Test 403 if user doesn't have enough permissions."""
        order = OrderFactory()
        url = reverse('admin:order_order_cancel', args=(order.pk, ))

        # create user with all order permissions apart from change
        user = create_test_user(
            is_staff=True,
            password=self.PASSWORD,
            permission_codenames=(
                OrderPermission.add,
                OrderPermission.delete,
                OrderPermission.view,
            ),
        )

        client = self.create_client(user=user)
        response = client.post(url, data={})
        assert response.status_code == 403
Пример #18
0
    def test_returns_error_if_adviser_has_no_sso_email_user_id(self):
        """If an adviser without an SSO email user ID is specified, an error should be returned."""
        user = create_test_user(is_staff=True,
                                is_superuser=True,
                                password=self.PASSWORD)
        adviser = AdviserFactory(sso_email_user_id=None)
        client = self.create_client(user=user)

        data = {
            'adviser': adviser.pk,
            'expires_in_hours': 10,
        }
        response = client.post(add_access_token_url, data=data)
        assert response.status_code == status.HTTP_200_OK

        form = response.context['form']
        assert form.errors == {
            'adviser': [NO_SSO_EMAIL_USER_ID_MESSAGE],
        }
Пример #19
0
    def test_all_with_view_document_permission(self):
        """Test getting all contacts with view document permission."""
        ContactFactory.create_batch(
            5, archived_documents_url_path='https://some-docs')

        user = create_test_user(permission_codenames=(
            'view_contact',
            'view_contact_document',
        ), )
        api_client = self.create_api_client(user=user)

        url = reverse('api-v3:contact:list')
        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK
        assert response.data['count'] == 5
        assert all(
            contact['archived_documents_url_path'] == 'https://some-docs'
            for contact in response.data['results'])
    def test_draft_update_enforces_required_fields(self, permissions, data, error_response):
        """
        Test that changing a draft to completed will enforce service and
        communication_channel to be set.
        """
        requester = create_test_user(permission_codenames=permissions)
        draft_interaction = CompanyInteractionFactory(
            kind=Interaction.KINDS.interaction,
            status=Interaction.STATUSES.draft,
            service_id=None,
            communication_channel=None,
        )
        api_client = self.create_api_client(user=requester)
        url = reverse('api-v3:interaction:item', kwargs={'pk': draft_interaction.pk})
        data = resolve_data(data)
        response = api_client.patch(url, data=data)

        assert(response.status_code == status.HTTP_400_BAD_REQUEST)
        assert response.data == error_response
Пример #21
0
    def test_adds_access_token_on_success(self, expires_in_hours):
        """The generated access token should be stored in the cache."""
        user = create_test_user(is_staff=True,
                                is_superuser=True,
                                password=self.PASSWORD)
        sso_email_user_id = '*****@*****.**'
        adviser = AdviserFactory(sso_email_user_id=sso_email_user_id)
        client = self.create_client(user=user)

        frozen_time = now()
        with freeze_time(frozen_time):
            data = {
                'adviser': adviser.pk,
                'expires_in_hours': expires_in_hours,
            }
            response = client.post(add_access_token_url,
                                   data=data,
                                   follow=True)

        assert response.status_code == status.HTTP_200_OK
        assert response.redirect_chain == [
            (admin_index_url, status.HTTP_302_FOUND),
        ]
        messages = list(response.context['messages'])
        assert len(messages) == 1

        success_message_text = messages[0].message
        search_pattern = r'<code style="user-select: all">(?P<token>[0-9a-zA-Z_-]+)</code>'
        match = re.search(search_pattern, success_message_text)
        assert match

        token = match.group('token')
        expected_expiry_time = frozen_time + timedelta(hours=expires_in_hours)

        with freeze_time(expected_expiry_time - timedelta(seconds=1)):
            assert cache.get(f'access_token:{token}') == {
                'email': adviser.email,
                'sso_email_user_id': sso_email_user_id,
            }

        with freeze_time(expected_expiry_time):
            assert cache.get(f'access_token:{token}') is None
    def test_link_does_not_exist_with_only_view_permission(self):
        """Test that the link does not exist for a user with only the view company permission."""
        company = CompanyFactory()

        change_route_name = admin_urlname(Company._meta, 'change')
        change_url = reverse(change_route_name, args=(company.pk,))

        user = create_test_user(
            permission_codenames=(CompanyPermission.view_company,),
            is_staff=True,
            password=self.PASSWORD,
        )
        client = self.create_client(user=user)
        response = client.get(change_url)
        assert response.status_code == status.HTTP_200_OK

        select_other_route_name = admin_urlname(Company._meta, 'merge-select-other-company')
        select_other_url = reverse(select_other_route_name)

        assert select_other_url not in response.rendered_content
Пример #23
0
    def test_permission_checking(self, permission_codenames, expected_status,
                                 api_client):
        """
        Test that the expected status is returned depending on the permissions the user has.
        """
        user = create_test_user(permission_codenames=permission_codenames)
        api_client = self.create_api_client(user=user)

        request_data = {
            'subject': 'Test referral',
            'company': {
                'id': CompanyFactory().pk,
            },
            'recipient': {
                'id': AdviserFactory().pk,
            },
        }

        response = api_client.post(collection_url, data=request_data)
        assert response.status_code == expected_status
Пример #24
0
    def test_who_am_i_active_features(self):
        """Active features should include the user's selected active features."""
        feature_flag = UserFeatureFlagFactory(code='test-feature', is_active=True)
        inactive_feature_flag = UserFeatureFlagFactory(code='inactive-feature', is_active=False)
        UserFeatureFlagFactory(code='another-feature', is_active=True)

        user = create_test_user()
        user.features.add(feature_flag, inactive_feature_flag)

        api_client = self.create_api_client(user=user)

        url = reverse('who_am_i')
        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()

        assert 'active_features' in response_data
        assert response_data['active_features'] == ['test-feature']
Пример #25
0
    def test_add_adviser_link_existence(
        self,
        permission_codenames,
        should_link_exist,
    ):
        """Test that there is a link to add an adviser from SSO if the user has the correct
        permissions.
        """
        user = create_test_user(
            permission_codenames=permission_codenames,
            password=self.PASSWORD,
            is_staff=True,
        )

        client = self.create_client(user)
        response = client.get(changelist_url)
        assert response.status_code == status.HTTP_200_OK

        assert (add_from_sso_url
                in response.rendered_content) == should_link_exist
Пример #26
0
    def test_user_with_permission_can_get_report(self):
        """Test get report by a user with permission."""
        report = SPIReportFactory()

        url = reverse(
            'investment-report:download-spi-report',
            kwargs={
                'pk': report.pk,
            },
        )
        user = create_test_user(
            is_staff=True,
            password=self.PASSWORD,
            permission_codenames=(SPIReportPermission.change, ),
        )
        client = self.create_client(user=user)
        response = client.get(url)

        assert response.status_code == status.HTTP_302_FOUND
        assert report.s3_key in response.url
    def test_link_does_not_exist_with_only_view_permission(self):
        """
        Test that the link does not exist for a user with only the view company permission.
        """
        list_route_name = admin_urlname(Company._meta, 'changelist')
        list_url = reverse(list_route_name)

        user = create_test_user(
            permission_codenames=(CompanyPermission.view_company,),
            is_staff=True,
            password=self.PASSWORD,
        )
        client = self.create_client(user=user)
        response = client.get(list_url)
        assert response.status_code == status.HTTP_200_OK

        company_link_route_name = admin_urlname(Company._meta, 'dnb-link-select-ids')
        company_link_url = reverse(company_link_route_name)

        assert company_link_url not in response.rendered_content
Пример #28
0
    def test_one_list_download(self):
        """Test the download of the One List."""
        CompanyFactory.create_batch(
            2,
            headquarter_type_id=constants.HeadquarterType.ghq.value.id,
            classification=random_obj_for_model(CompanyClassification),
            one_list_account_owner=AdviserFactory(),
        )
        # ignored because headquarter_type is None
        CompanyFactory(
            headquarter_type=None,
            classification=random_obj_for_model(CompanyClassification),
            one_list_account_owner=AdviserFactory(),
        )
        # ignored because classification is None
        CompanyFactory(
            headquarter_type_id=constants.HeadquarterType.ghq.value.id,
            classification=None,
            one_list_account_owner=AdviserFactory(),
        )
        # ignored because one_list_account_owner is None
        CompanyFactory(
            headquarter_type_id=constants.HeadquarterType.ghq.value.id,
            classification=random_obj_for_model(CompanyClassification),
            one_list_account_owner=None,
        )

        url = reverse('admin-report:download-report',
                      kwargs={'report_id': 'one-list'})

        user = create_test_user(
            permission_codenames=('view_company', ),
            is_staff=True,
            password=self.PASSWORD,
        )

        client = self.create_client(user=user)
        response = client.get(url)
        assert response.status_code == status.HTTP_200_OK
        # 3 = header + the first 2 companies
        assert len(response.getvalue().decode('utf-8').splitlines()) == 3
Пример #29
0
    def test_load_opt_outs_link_does_not_exist_if_only_has_view_permission(self):
        """
        Test that there is not a link to load email marketing opt outs if the user only has view
        (but not change) permission for contacts.
        """
        change_list_url = reverse(admin_urlname(Contact._meta, 'changelist'))
        user = create_test_user(
            permission_codenames=(ContactPermission.view_contact,),
            is_staff=True,
            password=self.PASSWORD,
        )

        client = self.create_client(user=user)
        response = client.get(change_list_url)
        assert response.status_code == status.HTTP_200_OK

        load_opt_outs_url = reverse(
            admin_urlname(Contact._meta, 'load-email-marketing-opt-outs'),
        )
        assert f'Select {Contact._meta.verbose_name} to view' in response.rendered_content
        assert load_opt_outs_url not in response.rendered_content
    def test_non_restricted_user_can_only_list_relevant_interactions(self, permissions):
        """Test that a non-restricted user can list all interactions"""
        requester = create_test_user(permission_codenames=permissions)
        api_client = self.create_api_client(user=requester)

        project = InvestmentProjectFactory()
        company = CompanyFactory()
        company_interactions = CompanyInteractionFactory.create_batch(3, company=company)
        project_interactions = CompanyInteractionFactory.create_batch(
            3, investment_project=project,
        )

        url = reverse('api-v3:interaction:collection')
        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['count'] == 6
        actual_ids = {i['id'] for i in response_data['results']}
        expected_ids = {str(i.id) for i in chain(project_interactions, company_interactions)}
        assert actual_ids == expected_ids