Beispiel #1
0
    def testRefreshFileStartsFlow(self):
        self.Open("/#/clients/C.0000000000000001/vfs/fs/os/c/Downloads/")

        # Select a file and start a flow by requesting a newer version.
        self.Click("css=tr:contains(\"a.txt\")")
        self.Click("css=li[heading=Download]")
        self.Click("css=button:contains(\"Collect from the client\")")

        # Create a new file version (that would have been created by the flow
        # otherwise) and finish the flow.

        # Make sure that the flow has started (when button is clicked, the HTTP
        # API request is sent asynchronously).
        def MultiGetFileStarted():
            return compatibility.GetName(transfer.MultiGetFile) in [
                f.flow_class_name
                for f in data_store.REL_DB.ReadAllFlowObjects(
                    client_id=self.client_id)
            ]

        self.WaitUntil(MultiGetFileStarted)

        flow_test_lib.FinishAllFlowsOnClient(self.client_id,
                                             check_flow_errors=False)

        time_in_future = rdfvalue.RDFDatetime.Now() + rdfvalue.DurationSeconds(
            "1h")
        # We have to make sure that the new version will not be within a second
        # from the current one, otherwise the previous one and the new one will
        # be indistinguishable in the UI (as it has a 1s precision when
        # displaying versions).
        gui_test_lib.CreateFileVersion(self.client_id,
                                       "fs/os/c/Downloads/a.txt",
                                       "The newest version!".encode("utf-8"),
                                       timestamp=time_in_future)

        # Once the flow has finished, the file view should update and add the
        # newly created, latest version of the file to the list. The selected
        # option should still be "HEAD".
        self.WaitUntilContains("HEAD", self.GetText,
                               "css=.version-dropdown > option[selected]")

        # The file table should also update and display the new timestamp.
        self.WaitUntilContains(gui_test_lib.DateTimeString(time_in_future),
                               self.GetText,
                               "css=.version-dropdown > option:nth(1)")

        # The file table should also update and display the new timestamp.
        self.WaitUntil(
            self.IsElementPresent,
            "css=grr-file-table tbody > tr td:contains(\"%s\")" %
            (gui_test_lib.DateTimeString(time_in_future)))

        # Make sure the file content has changed.
        self.Click("css=li[heading=TextView]")
        self.WaitUntilContains("The newest version!", self.GetText,
                               "css=div.monospace pre")

        # Go to the flow management screen and check that there was a new flow.
        self.Click("css=a:contains('Manage launched flows')")
        self.Click("css=grr-flows-list tr:contains('MultiGetFile')")
        self.WaitUntilContains(transfer.MultiGetFile.__name__, self.GetText,
                               "css=#main_bottomPane")

        self.WaitUntilContains(
            "c/Downloads/a.txt", self.GetText,
            "css=#main_bottomPane table > tbody td.proto_key:contains(\"Path\") "
            "~ td.proto_value")
Beispiel #2
0
    def testRefreshFileStartsFlow(self):
        self.Open("/")

        self.Type("client_query", "C.0000000000000001")
        self.Click("client_query_submit")

        self.WaitUntilEqual(u"C.0000000000000001", self.GetText,
                            "css=span[type=subject]")

        # Choose client 1.
        self.Click("css=td:contains('0001')")

        # Go to Browse VFS.
        self.Click("css=a:contains('Browse Virtual Filesystem')")

        self.Click("css=#_fs i.jstree-icon")
        self.Click("css=#_fs-os i.jstree-icon")
        self.Click("css=#_fs-os-c i.jstree-icon")

        # Test file versioning.
        self.WaitUntil(self.IsElementPresent, "css=#_fs-os-c-Downloads")
        self.Click("link=Downloads")

        # Select a file and start a flow by requesting a newer version.
        self.Click("css=tr:contains(\"a.txt\")")
        self.Click("css=li[heading=Download]")
        self.Click("css=button:contains(\"Collect from the client\")")

        # Create a new file version (that would have been created by the flow
        # otherwise) and finish the flow.
        client_id = rdf_client.ClientURN("C.0000000000000001")

        fd = aff4.FACTORY.Open(client_id.Add("flows"), token=self.token)

        # Make sure that the flow has started (when button is clicked, the HTTP
        # API request is sent asynchronously).
        def MultiGetFileStarted():
            return transfer.MultiGetFile.__name__ in list(
                x.__class__.__name__ for x in fd.OpenChildren())

        self.WaitUntil(MultiGetFileStarted)

        flows = list(fd.ListChildren())

        client_mock = action_mocks.MultiGetFileClientMock()
        for flow_urn in flows:
            flow_test_lib.TestFlowHelper(flow_urn,
                                         client_mock,
                                         client_id=client_id,
                                         check_flow_errors=False,
                                         token=self.token)

        time_in_future = rdfvalue.RDFDatetime.Now() + rdfvalue.Duration("1h")
        # We have to make sure that the new version will not be within a second
        # from the current one, otherwise the previous one and the new one will
        # be indistinguishable in the UI (as it has a 1s precision when
        # displaying versions).
        with test_lib.FakeTime(time_in_future):
            gui_test_lib.CreateFileVersion(
                rdf_client.ClientURN("C.0000000000000001"),
                "fs/os/c/Downloads/a.txt",
                "The newest version!",
                timestamp=rdfvalue.RDFDatetime.Now(),
                token=self.token)

        # Once the flow has finished, the file view should update and add the
        # newly created, latest version of the file to the list. The selected
        # option should still be "HEAD".
        self.WaitUntilContains("HEAD", self.GetText,
                               "css=.version-dropdown > option[selected]")

        # The file table should also update and display the new timestamp.
        self.WaitUntilContains(gui_test_lib.DateTimeString(time_in_future),
                               self.GetText,
                               "css=.version-dropdown > option:nth(1)")

        # The file table should also update and display the new timestamp.
        self.WaitUntil(
            self.IsElementPresent,
            "css=grr-file-table tbody > tr td:contains(\"%s\")" %
            (gui_test_lib.DateTimeString(time_in_future)))

        # Make sure the file content has changed.
        self.Click("css=li[heading=TextView]")
        self.WaitUntilContains("The newest version!", self.GetText,
                               "css=div.monospace pre")

        # Go to the flow management screen and check that there was a new flow.
        self.Click("css=a:contains('Manage launched flows')")
        self.Click("css=grr-flows-list tr:contains('MultiGetFile')")
        self.WaitUntilContains(transfer.MultiGetFile.__name__, self.GetText,
                               "css=#main_bottomPane")

        self.WaitUntilContains(
            "c/Downloads/a.txt", self.GetText,
            "css=#main_bottomPane table > tbody td.proto_key:contains(\"Path\") "
            "~ td.proto_value")
Beispiel #3
0
    def testVersionDropDownChangesFileContentAndDownloads(self):
        """Test the fileview interface."""

        self.Open("/#/clients/%s" % self.client_id)

        # Go to Browse VFS.
        self.Click("css=a[grrtarget='client.vfs']")

        self.Click("css=#_fs i.jstree-icon")
        self.Click("css=#_fs-os i.jstree-icon")
        self.Click("css=#_fs-os-c i.jstree-icon")

        # Test file versioning.
        self.WaitUntil(self.IsElementPresent, "css=#_fs-os-c-Downloads")
        self.Click("link=Downloads")

        # Verify that we have the latest version in the table by default.
        self.assertIn(gui_test_lib.DateString(gui_test_lib.TIME_2),
                      self.GetText("css=tr:contains(\"a.txt\")"))

        # Click on the row.
        self.Click("css=tr:contains(\"a.txt\")")
        self.WaitUntilContains("a.txt", self.GetText,
                               "css=div#main_bottomPane h1")
        self.WaitUntilContains("HEAD", self.GetText,
                               "css=.version-dropdown > option[selected]")

        self.WaitUntilContains(gui_test_lib.DateString(gui_test_lib.TIME_2),
                               self.GetText,
                               "css=.version-dropdown > option:nth(1)")

        # Check the data in this file.
        self.Click("css=li[heading=TextView]")
        self.WaitUntilContains("Goodbye World", self.GetText,
                               "css=div.monospace pre")

        downloaded_files = []

        def FakeDownloadHandle(unused_self, args, token=None):
            _ = token  # Avoid unused variable linter warnings.
            downloaded_files.append((args.file_path, args.timestamp))

            return api_call_handler_base.ApiBinaryStream(
                filename=os.path.basename(args.file_path),
                content_generator=range(42))

        with utils.Stubber(api_vfs.ApiGetFileBlobHandler, "Handle",
                           FakeDownloadHandle):
            # Try to download the file.
            self.Click("css=li[heading=Download]")

            self.WaitUntilContains(
                gui_test_lib.DateTimeString(gui_test_lib.TIME_2), self.GetText,
                "css=grr-file-download-view")
            self.Click("css=button:contains(\"Download\")")

            # Select the previous version.
            self.Click(
                "css=select.version-dropdown > option:contains(\"%s\")" %
                gui_test_lib.DateString(gui_test_lib.TIME_1))

            # Now we should have a different time.
            self.WaitUntilContains(
                gui_test_lib.DateTimeString(gui_test_lib.TIME_1), self.GetText,
                "css=grr-file-download-view")
            self.Click("css=button:contains(\"Download\")")

            self.WaitUntil(self.IsElementPresent, "css=li[heading=TextView]")

            # the FakeDownloadHandle method was actually called four times, since
            # a file download first sends a HEAD request to check user access.
            self.WaitUntil(lambda: len(downloaded_files) == 4)

        # Both files should be the same...
        self.assertEqual(downloaded_files[0][0], u"fs/os/c/Downloads/a.txt")
        self.assertEqual(downloaded_files[2][0], u"fs/os/c/Downloads/a.txt")
        # But from different times. The downloaded file timestamp is only accurate
        # to the nearest second.
        self.assertEqual(downloaded_files[0][1], None)
        self.assertAlmostEqual(downloaded_files[2][1],
                               gui_test_lib.TIME_1,
                               delta=rdfvalue.DurationSeconds("1s"))

        self.Click("css=li[heading=TextView]")

        # Make sure the file content has changed. This version has "Hello World" in
        # it.
        self.WaitUntilContains("Hello World", self.GetText,
                               "css=div.monospace pre")