Пример #1
0
def test_request_non_gitlab_visualisation_access(client, user, mocker):
    owner = factories.UserFactory()
    secondary_contact = factories.UserFactory()
    create_zendesk_ticket = mocker.patch(
        'dataworkspace.apps.datasets.views.create_zendesk_ticket'
    )
    create_zendesk_ticket.return_value = 999

    ds = factories.VisualisationCatalogueItemFactory.create(
        published=True,
        enquiries_contact=owner,
        secondary_enquiries_contact=secondary_contact,
        user_access_type='REQUIRES_AUTHORIZATION',
        visualisation_template=None,
    )
    VisualisationLinkFactory.create(
        visualisation_type='DATASTUDIO',
        visualisation_catalogue_item=ds,
        name='Visualisation datastudio',
        identifier='https://www.data.studio.test',
    )

    response = client.post(
        reverse('datasets:request_access', kwargs={'dataset_uuid': ds.id}),
        data={"email": "*****@*****.**", "goal": "My goal"},
        follow=True,
    )

    assert response.status_code == 200

    create_zendesk_ticket.assert_called_once_with(
        "*****@*****.**", mock.ANY, "My goal", mock.ANY, ds.name, mock.ANY, None, None
    )
Пример #2
0
    def test_first_time_user_without_tools_access_fails(
        self,
        mock_new_credentials,
        mock_source_tables,
        mock_cache,
        unauthenticated_client,
        dataset_db,
    ):
        credentials = [{"db_user": "******", "db_password": "******"}]
        mock_cache.get.side_effect = [
            1,  # cache.get(credentials_version_key, None)
            None,  # cache.get(cache_key, None)
        ]
        mock_new_credentials.return_value = credentials

        user = factories.UserFactory()

        header = {
            "HTTP_SSO_PROFILE_USER_ID": user.profile.sso_id,
            "HTTP_HOST": f"superset-edit.{settings.APPLICATION_ROOT_DOMAIN}",
        }
        response = unauthenticated_client.get(
            reverse("api-v1:core:get-superset-role-credentials"), **header)
        assert response.status_code == status.HTTP_401_UNAUTHORIZED
        assert not mock_new_credentials.called
        assert mock_cache.set.call_args_list == [
            mock.call("superset_credentials_version", 1, nx=True,
                      timeout=None),
        ]
Пример #3
0
    def test_returning_user_succeeds(
        self,
        mock_new_credentials,
        mock_source_tables,
        mock_cache,
        unauthenticated_client,
        dataset_db,
    ):
        credentials = [{"db_user": "******", "db_password": "******"}]
        mock_cache.get.side_effect = [
            1,  # cache.get(credentials_version_key, None)
            {
                "credentials": credentials[0],
                "dashboards": [],
            },  # cache.get(cache_key, None)
        ]
        mock_new_credentials.return_value = credentials

        user = factories.UserFactory()

        header = {
            "HTTP_SSO_PROFILE_USER_ID": user.profile.sso_id,
            "HTTP_HOST": f"superset-edit.{settings.APPLICATION_ROOT_DOMAIN}",
        }
        response = unauthenticated_client.get(
            reverse("api-v1:core:get-superset-role-credentials"), **header)
        assert response.status_code == status.HTTP_200_OK
        assert response.json()["credentials"] == credentials[0]
        assert response.json()["dashboards"] == []

        assert not mock_new_credentials.called
        assert mock_cache.set.call_args_list == [
            mock.call("superset_credentials_version", 1, nx=True,
                      timeout=None),
        ]
Пример #4
0
    def test_db_user_record(self):
        user_count = DatabaseUser.objects.count()

        user = factories.UserFactory()
        source_tables = source_tables_for_user(user)
        db_role_schema_suffix = db_role_schema_suffix_for_user(user)
        new_private_database_credentials(
            db_role_schema_suffix,
            source_tables,
            user.email,
            user,
            valid_for=datetime.timedelta(days=31),
        )
        assert DatabaseUser.objects.count() == user_count + 1
Пример #5
0
    def test_public_user_gets_db_access(self, mock_cache,
                                        unauthenticated_client, dataset_db):
        visualisation = factories.VisualisationLinkFactory(
            visualisation_type="SUPERSET",
            visualisation_catalogue_item__user_access_type=UserAccessType.
            REQUIRES_AUTHENTICATION,
        )
        credentials = {
            "memorable_name": "my_database",
            "db_name": "test_datasets",
            "db_host": "data-workspace-postgres",
            "db_port": "5432",
            "db_user": "******",
            "db_password": "******",
        }
        mock_cache.get.side_effect = [
            1,  # cache.get(credentials_version_key, None)
            None,  # cache.get(cache_key, None)
        ]

        user = factories.UserFactory()
        tools_permission = Permission.objects.get(
            codename="start_all_applications",
            content_type=ContentType.objects.get_for_model(
                ApplicationInstance),
        )
        user.user_permissions.add(tools_permission)

        headers = {
            "HTTP_SSO_PROFILE_USER_ID": user.profile.sso_id,
            "HTTP_HOST": f"superset.{settings.APPLICATION_ROOT_DOMAIN}",
        }
        response = unauthenticated_client.get(
            reverse("api-v1:core:get-superset-role-credentials"), **headers)
        assert response.status_code == status.HTTP_200_OK
        assert response.json()["credentials"] == credentials
        assert response.json()["dashboards"] == [visualisation.identifier]

        assert mock_cache.set.call_args_list == [
            mock.call("superset_credentials_version", 1, nx=True,
                      timeout=None),
            mock.call(
                f"superset_credentials_1_view_{user.profile.sso_id}",
                {
                    "credentials": credentials,
                    "dashboards": [visualisation.identifier]
                },
                timeout=mock.ANY,
            ),
        ]
Пример #6
0
    def test_success(self, unauthenticated_client):
        datacut = factories.DatacutDataSetFactory(
            information_asset_owner=factories.UserFactory(),
            information_asset_manager=factories.UserFactory(),
            enquiries_contact=factories.UserFactory(),
            personal_data='personal',
            retention_policy='retention',
            eligibility_criteria=['eligibility'],
        )
        datacut.tags.set([factories.SourceTagFactory()])

        master_dataset = factories.MasterDataSetFactory(
            information_asset_owner=factories.UserFactory(),
            information_asset_manager=factories.UserFactory(),
            personal_data='personal',
            retention_policy='retention',
        )
        factories.SourceTableFactory(dataset=master_dataset,
                                     schema='public',
                                     table='test_table1')
        factories.SourceTableFactory(dataset=master_dataset,
                                     schema='public',
                                     table='test_table1')
        reference_dataset = factories.ReferenceDatasetFactory(
            information_asset_owner=factories.UserFactory(), )

        visualisation = factories.VisualisationCatalogueItemFactory(
            personal_data='personal', )

        visualisation2 = factories.VisualisationCatalogueItemFactory(
            published=False)

        response = unauthenticated_client.get(self.url)
        assert response.status_code == status.HTTP_200_OK
        assert response.json()['results'] == [
            self.expected_response(
                datacut,
                'Data cut',
                datacut.personal_data,
                datacut.retention_policy,
                datacut.eligibility_criteria,
            ),
            self.expected_response(
                master_dataset,
                'Master dataset',
                master_dataset.personal_data,
                master_dataset.retention_policy,
            ),
            self.expected_response(
                reference_dataset,
                'Reference data',
            ),
            self.expected_response(visualisation, 'Visualisation',
                                   visualisation.personal_data),
            self.expected_response(visualisation2, 'Visualisation'),
        ]
Пример #7
0
    def test_success(self, unauthenticated_client):
        datacut = factories.DatacutDataSetFactory(
            information_asset_owner=factories.UserFactory(),
            information_asset_manager=factories.UserFactory(),
            enquiries_contact=factories.UserFactory(),
            personal_data="personal",
            retention_policy="retention",
            eligibility_criteria=["eligibility"],
        )
        datacut.tags.set([factories.SourceTagFactory()])

        master_dataset = factories.MasterDataSetFactory(
            information_asset_owner=factories.UserFactory(),
            information_asset_manager=factories.UserFactory(),
            personal_data="personal",
            retention_policy="retention",
        )
        factories.SourceTableFactory(dataset=master_dataset,
                                     schema="public",
                                     table="test_table1")
        factories.SourceTableFactory(dataset=master_dataset,
                                     schema="public",
                                     table="test_table1")
        reference_dataset = factories.ReferenceDatasetFactory(
            information_asset_owner=factories.UserFactory(), )

        visualisation = factories.VisualisationCatalogueItemFactory(
            personal_data="personal", )

        visualisation2 = factories.VisualisationCatalogueItemFactory(
            published=False)

        response = unauthenticated_client.get(self.url)
        assert response.status_code == status.HTTP_200_OK
        assert response.json()["results"] == [
            self.expected_response(
                datacut,
                "Data cut",
                datacut.personal_data,
                datacut.retention_policy,
                datacut.eligibility_criteria,
            ),
            self.expected_response(
                master_dataset,
                "Master dataset",
                master_dataset.personal_data,
                master_dataset.retention_policy,
            ),
            self.expected_response(
                reference_dataset,
                "Reference data",
            ),
            self.expected_response(visualisation, "Visualisation",
                                   visualisation.personal_data),
            self.expected_response(visualisation2, "Visualisation"),
        ]
Пример #8
0
    def test_first_time_user_with_tools_access_succeeds(
        self,
        mock_new_credentials,
        mock_source_tables,
        mock_cache,
        unauthenticated_client,
        dataset_db,
    ):
        credentials = [{"db_user": "******", "db_password": "******"}]
        mock_cache.get.side_effect = [
            1,  # cache.get(credentials_version_key, None)
            None,  # cache.get(cache_key, None)
        ]
        mock_new_credentials.return_value = credentials

        user = factories.UserFactory()
        tools_permission = Permission.objects.get(
            codename="start_all_applications",
            content_type=ContentType.objects.get_for_model(
                ApplicationInstance),
        )
        user.user_permissions.add(tools_permission)

        headers = {
            "HTTP_SSO_PROFILE_USER_ID": user.profile.sso_id,
            "HTTP_HOST": f"superset-edit.{settings.APPLICATION_ROOT_DOMAIN}",
        }
        response = unauthenticated_client.get(
            reverse("api-v1:core:get-superset-role-credentials"), **headers)
        assert response.status_code == status.HTTP_200_OK
        assert response.json()["credentials"] == credentials[0]
        assert response.json()["dashboards"] == []

        assert mock_new_credentials.called
        assert mock_cache.set.call_args_list == [
            mock.call("superset_credentials_version", 1, nx=True,
                      timeout=None),
            mock.call(
                f"superset_credentials_1_edit_{user.profile.sso_id}",
                {
                    "credentials": credentials[0],
                    "dashboards": []
                },
                timeout=mock.ANY,
            ),
        ]
Пример #9
0
def test_request_visualisation_access(client, user, mocker):
    owner = factories.UserFactory()
    secondary_contact = factories.UserFactory()

    create_zendesk_ticket = mocker.patch(
        'dataworkspace.apps.datasets.views.create_support_request')
    create_zendesk_ticket.return_value = 123

    send_email = mocker.patch('dataworkspace.apps.datasets.views.send_email')

    ds = factories.VisualisationCatalogueItemFactory.create(
        published=True,
        enquiries_contact=owner,
        secondary_enquiries_contact=secondary_contact,
        visualisation_template__gitlab_project_id=321,
    )

    response = client.post(
        reverse('datasets:request_access', kwargs={'dataset_uuid': ds.id}),
        data={
            "email": "*****@*****.**",
            "goal": "my goal"
        },
        follow=True,
    )

    assert response.status_code == 200

    create_zendesk_ticket.assert_called_once_with(
        mock.ANY,
        mock.ANY,
        mock.ANY,
        subject=f"Data visualisation access request received - {ds.name}",
        tag="visualisation-access-request",
    )

    send_email.assert_has_calls(
        [
            mock.call(
                mock.ANY,
                owner.email,
                personalisation={
                    "visualisation_name": ds.name,
                    "visualisation_url":
                    f"http://testserver/datasets/{ds.id}#{ds.slug}",
                    "user_email": "*****@*****.**",
                    "people_url":
                    "https://people.trade.gov.uk/search?search_filters[]=people&query=Frank%20Exampleson",
                    "give_access_url": mock.ANY,
                    "goal": "my goal",
                },
            ),
            mock.call(
                mock.ANY,
                secondary_contact.email,
                personalisation={
                    "visualisation_name": ds.name,
                    "visualisation_url":
                    f"http://testserver/datasets/{ds.id}#{ds.slug}",
                    "user_email": "*****@*****.**",
                    "people_url":
                    "https://people.trade.gov.uk/search?search_filters[]=people&query=Frank%20Exampleson",
                    "give_access_url": mock.ANY,
                    "goal": "my goal",
                },
            ),
        ],
        any_order=True,
    )
Пример #10
0
def test_update_dataset_averages(metadata_db):
    # Events over 28 days old should be ignored
    dataset = factories.DataSetFactory.create(published_at=datetime.now() -
                                              timedelta(days=30),
                                              name="test_table")
    table = factories.SourceTableFactory.create(
        dataset=dataset,
        database=metadata_db,
        schema="public",
        table="test_table",
    )
    user = factories.UserFactory(email="*****@*****.**")

    factories.ToolQueryAuditLogTableFactory(
        table=table.table,
        audit_log__user=user,
        audit_log__timestamp=datetime(2021, 1, 1, tzinfo=timezone.utc),
    )

    assert calculate_dataset_average(dataset) == 0

    # Events that happened today should be ignored
    factories.ToolQueryAuditLogTableFactory(
        table=table.table,
        audit_log__user=user,
        audit_log__timestamp=datetime(2021, 1, 1, tzinfo=timezone.utc),
    )

    assert calculate_dataset_average(dataset) == 0

    # Events published within the last 28 days should be included
    # in the calculation
    dataset = factories.DataSetFactory.create(published_at=datetime.now() -
                                              timedelta(days=30),
                                              name="test_table")
    table = factories.SourceTableFactory.create(
        dataset=dataset,
        schema="public",
        table="test_table",
    )
    log_1 = factories.ToolQueryAuditLogFactory(user=user,
                                               timestamp=datetime.now() -
                                               timedelta(days=20))
    log_2 = factories.ToolQueryAuditLogFactory(user=user,
                                               timestamp=datetime.now() -
                                               timedelta(days=20))
    log_3 = factories.ToolQueryAuditLogFactory(user=user,
                                               timestamp=datetime.now() -
                                               timedelta(days=15))
    factories.ToolQueryAuditLogTableFactory(table=table.table,
                                            schema=table.schema,
                                            audit_log=log_1)
    factories.ToolQueryAuditLogTableFactory(table=table.table,
                                            schema=table.schema,
                                            audit_log=log_2)

    assert calculate_dataset_average(dataset) == 0.03571428571428571

    factories.ToolQueryAuditLogTableFactory(table=table.table,
                                            schema=table.schema,
                                            audit_log=log_3)

    assert calculate_dataset_average(dataset) == 0.07142857142857142

    unrelated_dataset = factories.DataSetFactory.create(
        published_at=datetime.now() - timedelta(days=30), name="test_table")

    assert calculate_dataset_average(unrelated_dataset) == 0