Skip to content

Commit

Permalink
Multiple changes.
Browse files Browse the repository at this point in the history
* Bump GRR version for open source release.
* Making file results table usable.
  • Loading branch information
mol123 committed Jul 1, 2020
1 parent 17f9f3e commit 8588f8c
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ def testCorrectlyDisplaysSuccessStateForSingleBrowser(self):
self.Open(f"/v2/clients/{self.client_id}")
# Expand the flow.
self.Click("css=.flow-title:contains('Browser History')")
self.WaitUntil(
self.IsElementPresent,
"css=.row:contains('Chrome') .success:contains('1 file collected')")
self.WaitUntil(self.IsElementPresent,
"css=.row:contains('Chrome') .success:contains('1 file')")
# Check that other browsers are not shown.
self.WaitUntilNot(self.IsElementPresent, "css=.row:contains('Opera')")
self.WaitUntilNot(self.IsElementPresent, "css=.row:contains('Safari')")
Expand Down Expand Up @@ -258,6 +257,45 @@ def testDisplaysMultipleResultsForSingleBrowser(self):
self.WaitUntilNot(self.IsElementPresent,
"css=button:contains('Load more')")

def testAllowsCopyingResultPathToClipboard(self):
flow_args = webhistory.CollectBrowserHistoryArgs(
browsers=[webhistory.CollectBrowserHistoryArgs.Browser.CHROME])
flow_id = flow_test_lib.StartFlow(
webhistory.CollectBrowserHistory,
creator=self.token.username,
client_id=self.client_id,
flow_args=flow_args)

flow_test_lib.AddResultsToFlow(
self.client_id,
flow_id, [_GenResults(webhistory.Browser.CHROME, 0)],
tag="CHROME")

with flow_test_lib.FlowProgressOverride(
webhistory.CollectBrowserHistory,
webhistory.CollectBrowserHistoryProgress(browsers=[
webhistory.BrowserProgress(
browser=webhistory.Browser.CHROME,
status=webhistory.BrowserProgress.Status.SUCCESS,
num_collected_files=1,
),
])):
self.Open(f"/v2/clients/{self.client_id}")
# Expand the flow.
self.Click("css=.flow-title:contains('Browser History')")
# Expand the browser.
self.Click("css=div.title:contains('Chrome')")
# Hover and click on the copy button.
self.MoveMouseTo(
"css=.results tr:nth(1):contains('/home/foo/chrome-0') td.path")
# Click on the now visible button.
self.Click(
"css=.results tr:nth(1):contains('/home/foo/chrome-0') td.path "
"button.copy-button")

clip_value = self.GetClipboard()
self.assertEqual(clip_value, "/home/foo/chrome-0")

def testDisplaysAndHidesResultsForSingleBrowser(self):
flow_args = webhistory.CollectBrowserHistoryArgs(browsers=[
webhistory.CollectBrowserHistoryArgs.Browser.CHROME,
Expand Down
4 changes: 2 additions & 2 deletions grr/server/grr_response_server/gui/ui/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Frontend

## Development server
First make sure `grr_admin_ui` is up and running.

Run `ng serve` (or `ng s`) for a dev server. Navigate to
`http://localhost:4200/`. The app will automatically reload if you change any of the source files.
`http://localhost:5432/`. The app will automatically reload if you change any of
the source files.

## Running unit tests

Expand Down
3 changes: 1 addition & 2 deletions grr/server/grr_response_server/gui/ui/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ui:build",
"proxyConfig": "proxy.conf.json"
"browserTarget": "ui:build"
},
"configurations": {
"production": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,29 @@
<thead>
<tr>
<th class="path">Path</th>
<th class="hash">Hash</th>
<th class="number">Mode</th>
<th class="number">Uid</th>
<th class="number">Gid</th>
<th class="number">Size</th>
<th class="timestamp">A-time</th>
<th class="timestamp">M-time</th>
<th class="timestamp">C-time</th>
<th class="timestamp">B-time</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let r of rows$ | async; trackBy: trackByRowIndex">
<td class="path">{{ r.path }}</td>
<td class="path">
{{ r.path }}&nbsp;<button class="copy-button" [cdkCopyToClipboard]="r.path" mat-icon-button aria-label="Copy path to clipboard">
<mat-icon class="menu-icon">content_copy</mat-icon>
</button>
</td>
<td class="hash"></td>
<td class="number">{{ r.mode | fileMode }}</td>
<td class="number">{{ r.uid }}</td>
<td class="number">{{ r.gid }}</td>
<td class="number">{{ r.size }}</td>
<td class="timestamp">{{ r.atime | date:'yyyy-MM-dd hh:mm:ss':'UTC' }}</td>
<td class="timestamp">{{ r.mtime | date:'yyyy-MM-dd hh:mm:ss':'UTC' }}</td>
<td class="timestamp">{{ r.ctime | date:'yyyy-MM-dd hh:mm:ss':'UTC' }}</td>
<td class="timestamp">{{ r.btime | date:'yyyy-MM-dd hh:mm:ss':'UTC' }}</td>
</tr>
</tbody>
</table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
@use '~material-theme' as c;

table {
font-size: 80%;
border-spacing: 0;
color: c.mat-color(c.$foreground, text-light);
font-size: 14px;
padding: 1em 0;
width: 100%;

th {
font-weight: normal;
border-bottom: none !important;
font-weight: 500;
text-align: left;
padding-bottom: 1.5em;
}

th,
td {
border-bottom: 1px solid c.mat-color(c.$foreground, divider-light);
padding-right: 1.5em;
vertical-align: top;
}

th:first-child,
td:first-child {
padding-left: 24px;
}

th:last-child,
td:last-child {
padding-right: 24px;
}

tbody {
td {
border-bottom: 1px solid c.mat-color(c.$foreground, divider);
padding-top: 0.5em;
padding-bottom: 0.5em;
}
Expand All @@ -28,8 +43,30 @@ table {
}

.path {
word-break: break-word;
min-width: 200px;
width: 30%;

.copy-button {
font-size: 16px;
visibility: hidden;

line-height: 18px !important;
height: 18px !important;
width: 18px !important;

mat-icon {
font-size: 16px;
}
}

&:hover .copy-button {
visibility: visible;
}
}

.number {
white-space: nowrap;
}

.timestamp {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ declare interface TableRow {
readonly atime?: Date;
readonly mtime?: Date;
readonly ctime?: Date;
readonly btime?: Date;
}


Expand Down Expand Up @@ -74,6 +75,7 @@ export class FileResultsTable {
atime: createOptionalDateSeconds(e.statEntry.stAtime),
mtime: createOptionalDateSeconds(e.statEntry.stMtime),
ctime: createOptionalDateSeconds(e.statEntry.stCtime),
btime: createOptionalDateSeconds(e.statEntry.stCrtime),
};
});
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,11 @@ describe('FileResultsTable Component', () => {
stMode: '420', // 0644
stDev: 16777220 + index,
stNlink: 1 + index,
stUid: 237586 + index,
stGid: 89939 + index,
stSize: `${index + 1}42`,
stAtime: `${index + 1}40000`,
stMtime: `${index + 1}400000`,
stCtime: `${index + 1}4000000`,
stCrtime: `${index + 1}40000000`,
};
}

Expand All @@ -85,14 +84,14 @@ describe('FileResultsTable Component', () => {
expect(rows.length).toBe(2);

const cells = rows[1].querySelectorAll('td');
expect(cells[0].innerText).toBe('/home/foo/bar/0');
expect(cells[1].innerText).toBe('-rw-r--r--');
expect(cells[2].innerText).toBe('237586');
expect(cells[3].innerText).toBe('89939');
expect(cells[4].innerText).toBe('142');
expect(cells[5].innerText).toBe('1970-01-02 02:53:20');
expect(cells[6].innerText).toBe('1970-01-17 04:53:20');
expect(cells[7].innerText).toBe('1970-06-12 12:53:20');
expect(cells[0].innerText.trim()).toBe('/home/foo/bar/0');
// No support for hashes yet, ignoring cell #1.
expect(cells[2].innerText).toBe('-rw-r--r--');
expect(cells[3].innerText).toBe('142');
expect(cells[4].innerText).toBe('1970-01-02 02:53:20');
expect(cells[5].innerText).toBe('1970-01-17 04:53:20');
expect(cells[6].innerText).toBe('1970-06-12 12:53:20');
expect(cells[7].innerText).toBe('1974-06-09 08:53:20');
});

it('correctly presents 2 rows', () => {
Expand All @@ -109,24 +108,24 @@ describe('FileResultsTable Component', () => {
expect(rows.length).toBe(3);

let cells = rows[1].querySelectorAll('td');
expect(cells[0].innerText).toBe('/home/foo/bar/0');
expect(cells[1].innerText).toBe('-rw-r--r--');
expect(cells[2].innerText).toBe('237586');
expect(cells[3].innerText).toBe('89939');
expect(cells[4].innerText).toBe('142');
expect(cells[5].innerText).toBe('1970-01-02 02:53:20');
expect(cells[6].innerText).toBe('1970-01-17 04:53:20');
expect(cells[7].innerText).toBe('1970-06-12 12:53:20');
expect(cells[0].innerText.trim()).toBe('/home/foo/bar/0');
// No support for hashes yet, ignoring cell #1.
expect(cells[2].innerText).toBe('-rw-r--r--');
expect(cells[3].innerText).toBe('142');
expect(cells[4].innerText).toBe('1970-01-02 02:53:20');
expect(cells[5].innerText).toBe('1970-01-17 04:53:20');
expect(cells[6].innerText).toBe('1970-06-12 12:53:20');
expect(cells[7].innerText).toBe('1974-06-09 08:53:20');

cells = rows[2].querySelectorAll('td');
expect(cells[0].innerText).toBe('/home/foo/bar/1');
expect(cells[1].innerText).toBe('-rw-r--r--');
expect(cells[2].innerText).toBe('237587');
expect(cells[3].innerText).toBe('89940');
expect(cells[4].innerText).toBe('242');
expect(cells[5].innerText).toBe('1970-01-03 06:40:00');
expect(cells[6].innerText).toBe('1970-01-28 06:40:00');
expect(cells[7].innerText).toBe('1970-10-05 06:40:00');
expect(cells[0].innerText.trim()).toBe('/home/foo/bar/1');
// No support for hashes yet, ignoring cell #1.
expect(cells[2].innerText).toBe('-rw-r--r--');
expect(cells[3].innerText).toBe('242');
expect(cells[4].innerText).toBe('1970-01-03 06:40:00');
expect(cells[5].innerText).toBe('1970-01-28 06:40:00');
expect(cells[6].innerText).toBe('1970-10-05 06:40:00');
expect(cells[7].innerText).toBe('1977-08-09 06:40:00');
});


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {ClipboardModule} from '@angular/cdk/clipboard';
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {RouterModule} from '@angular/router';
import {FileModePipe} from '@app/components/flow_details/helpers/file_mode_pipe';
Expand All @@ -18,7 +20,9 @@ import {FileResultsTable} from './file_results_table';
RouterModule,
CommonModule,
// Angular Material modules.
ClipboardModule,
MatButtonModule,
MatIconModule,
],
declarations: [
FileResultsTable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@
<div class="row" *ngFor="let row of browserRows$ | async; trackBy: trackByRowName">
<div class="header" (click)="rowClicked(row)">
<div class="title">
<span *ngIf="row.progress.numCollectedFiles > 0 " class="material-icons arrow-icon">
{{ expandedRows[row.name] ? 'arrow_drop_down' : 'arrow_right' }}
</span>
<span>{{ row.friendlyName }}</span>
</div>

<div class="error" *ngIf="row.progress.status === 'ERROR'">
{{ row.progress.description }}
<div class="flow-details-summary-aligned">
<span class="row-text">{{ row.progress.description }}</span>
</div>
<span class="material-icons">error</span>
</div>

Expand All @@ -34,13 +33,23 @@
</div>

<div class="success" *ngIf="row.progress.status === 'SUCCESS' && row.progress.numCollectedFiles > 0">
{{ row.progress.numCollectedFiles | i18nPlural: {'=1': '1 file', 'other': '# files'} }} collected
<div class="flow-details-summary-aligned">
<span class="row-text">{{ row.progress.numCollectedFiles | i18nPlural: {'=1': '1 file', 'other': '# files'} }}</span>
</div>
<span class="material-icons">check_circle</span>
</div>

<div class="warning" *ngIf="row.progress.status === 'SUCCESS' && row.progress.numCollectedFiles === 0">
No files collected
<span class="material-icons">warning</span>
<div class="flow-details-summary-aligned">
<span class="row-text">No files collected</span>
</div>
<span class="material-icons">warning</span>
</div>

<div class="expansion-indicator">
<span *ngIf="row.progress.numCollectedFiles > 0 " class="material-icons arrow-icon">
{{ expandedRows[row.name] ? 'keyboard_arrow_down' : 'keyboard_arrow_right' }}
</span>
</div>
</div>

Expand Down

0 comments on commit 8588f8c

Please sign in to comment.