Skip to content

Commit

Permalink
This is server 0.3-6.
Browse files Browse the repository at this point in the history
- Some bugfixes to the server build process.
- Changing the client search to return all clients when searching for
- "." or the empty string.
  • Loading branch information
grrrrrrrrr committed Apr 17, 2015
1 parent 59adfb2 commit 757f5df
Show file tree
Hide file tree
Showing 91 changed files with 1,462 additions and 6,428 deletions.
2 changes: 1 addition & 1 deletion client/client_actions/action_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def testIteratedListDirectory(self):
# Reset the st_atime in the results to avoid potential flakiness.
x.st_atime = y.st_atime = 0

self.assertProtoEqual(x, y)
self.assertRDFValueEqual(x, y)

def testSuspendableListDirectory(self):
request = rdfvalue.ListDirRequest()
Expand Down
2 changes: 1 addition & 1 deletion client/client_actions/searching_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def testFindAction(self):
request.iterator = result[1].Copy()

for x, y in zip(all_files, files):
self.assertProtoEqual(x, y)
self.assertRDFValueEqual(x, y)

# Make sure the iterator is finished
self.assertEqual(request.iterator.state, rdfvalue.Iterator.State.FINISHED)
Expand Down
3 changes: 2 additions & 1 deletion client/client_utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ def testLinuxNannyLog(self):
grr_message = rdfvalue.GrrMessage(session_id="W:test")

nanny_controller.WriteTransactionLog(grr_message)
self.assertProtoEqual(grr_message, nanny_controller.GetTransactionLog())
self.assertRDFValueEqual(grr_message,
nanny_controller.GetTransactionLog())
nanny_controller.CleanTransactionLog()

self.assert_(nanny_controller.GetTransactionLog() is None)
Expand Down
9 changes: 9 additions & 0 deletions client/linux/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
gnureadline==6.3.3
pexpect==3.3
psutil==2.1.3
pycrypto==2.6.1
pyinstaller==2.1
python-dateutil==2.3
pytz==2014.10
rekall==1.3.1
urllib3==1.10
7 changes: 7 additions & 0 deletions client/windows/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
psutil==2.1.3
pycrypto==2.6.1
pyinstaller==2.1
python-dateutil==2.3
pytz==2014.10
rekall==1.3.1
urllib3==1.10
2 changes: 0 additions & 2 deletions config/debian/dpkg_server/rules
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ override_dh_installinit:
rm debian/grr-server/etc/init/grr-client.conf
# Set up grr-server shared directories and files
mkdir -p debian/grr-server/usr/share/grr/scripts
mkdir -p debian/grr-server/usr/share/grr/scripts/signing/windows
mkdir -p debian/grr-server/usr/share/grr/binaries
mkdir -p debian/grr-server/usr/share/grr/executables/linux/installers/
mkdir -p debian/grr-server/usr/share/grr/executables/darwin/installers/
Expand All @@ -50,7 +49,6 @@ override_dh_installinit:
mkdir -p $(shell ls -d executables/*/templates/ |sed 's/executables/debian\/grr-server\/usr\/share\/grr\/executables/g')

install -p -m755 scripts/*sh debian/grr-server/usr/share/grr/scripts/
install -p -m755 scripts/signing/windows/*sh debian/grr-server/usr/share/grr/scripts/signing/windows/

# Make a copy of the default config so users can refer to it.
install -p -m644 -T config/grr-server.yaml debian/grr-server/usr/share/grr/grr-server.yaml.default
Expand Down
2 changes: 2 additions & 0 deletions config/grr-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ ClientBuilder Context:
ClientBuilder.target_dir: |
/usr/lib64/%(Client.name)/%(ClientBuilder.output_basename)
ClientBuilder.template_extension: .rpm.zip

Client.install_path: |
/usr/lib64/%(Client.name)/%(ClientBuilder.output_basename)
Expand Down
97 changes: 97 additions & 0 deletions gui/Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Gruntfile for GRR UI frontend code.
* @param {*} grunt
*/
module.exports = function(grunt) {

var closureCompiler = require('superstartup-closure-compiler');

// Find all mentioned third-party JS files in the base.html template file.
// As order of these files is important, we can't use glob to concat them,
// but have to rely on order specified in base.html.
var getThirdPartyJsFiles = function() {
var baseTemplate = grunt.file.read('templates/base.html');
var re = /<script src="\/(static\/third-party\/.+\.js)"/gm;
var result = [];

while (match = re.exec(baseTemplate)) {
if (match[1] != 'static/third-party/third-party.bundle.js') {
result.push(match[1]);
}

re.lastIndex = match.index + 1;
}

return result;
};

// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
closureCompiler: {
options: {
compilerFile: closureCompiler.getPath(),
compilerOpts: {
language_in: 'ECMASCRIPT5',
angular_pass: 'true',
compilation_level: 'WHITESPACE_ONLY',
create_source_map: 'static/grr-ui.bundle.js.map',
summary_detail_level: 3,
closure_entry_point: 'grrUi.appController.module',
manage_closure_dependencies: 'true'
}
},
// GRR UI Javascript sources are compiled via Closure compiler.
compileUiBundleJs: {
src: ['static/javascript/closure/base.js',
'static/angular-components/**/*.js',
'!static/angular-components/**/*_test.js'],
dest: 'static/grr-ui.bundle.js'
},
},
concat: {
// GRR UI CSS sources are just concatenated.
compileUiBundleCss: {
src: ['static/css/**/*.css'],
dest: 'static/grr-ui.bundle.css'
},
// Third-party JS files are concatenated in the order of their
// appearance in base.html.
compileThirdPartyBundleJs: {
src: getThirdPartyJsFiles(),
dest: 'static/third-party/third-party.bundle.js'
},
// Third-party CSS files are just concatenated.
compileThirdPartyBundleCss: {
src: ['static/third-party/**/*.css'],
dest: 'static/third-party/third-party.bundle.css'
}
},
closureDepsWriter: {
options: {
depswriter: '/usr/local/bin/depswriter.py',
root_with_prefix: '"static/angular-components ../../angular-components"'
},
// GRR closure deps file is regenerated with depswriter.py.
genDeps: {
dest: 'static/javascript/closure/deps.js'
}
}
});

// "compile" task recompiles all dynamically generated files.
grunt.registerTask('compile', ['closureCompiler:compileUiBundleJs',
'concat:compileUiBundleCss',
'concat:compileThirdPartyBundleJs',
'concat:compileThirdPartyBundleCss',
'closureDepsWriter:genDeps']);

// Load closure compiler plugin.
grunt.loadNpmTasks('grunt-closure-tools');

// Load concat plugin.
grunt.loadNpmTasks('grunt-contrib-concat');

// Default task(s).
grunt.registerTask('default', ['compile']);
};
8 changes: 5 additions & 3 deletions gui/api_plugins/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,18 @@ def Render(self, args, token=None):
end = args.count or sys.maxint
rendered_clients = []

keywords = shlex.split(args.query)
# An empty query matches all clients, use the universal keyword ".".
query = args.query or "."
keywords = shlex.split(query)
if not keywords:
raise ValueError("Can't search with empty query string.")
raise ValueError("Couldn't parse query string.")

index = aff4.FACTORY.Create(client_index.MAIN_INDEX,
aff4_type="ClientIndex",
mode="rw",
token=token)
result_urns = sorted(index.LookupClients(keywords),
key=str)[args.offset:end]
key=str)[args.offset:args.offset + end]
result_set = aff4.FACTORY.MultiOpen(result_urns, token=token)

for child in result_set:
Expand Down
24 changes: 8 additions & 16 deletions gui/api_value_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,6 @@ class ApiRDFProtoStructRenderer(ApiValueRenderer):

processors = []

descriptors_cache = {}

def RenderValue(self, value):
result = value.AsDict()
for k, v in value.AsDict().items():
Expand All @@ -282,20 +280,14 @@ def RenderValue(self, value):
result = self._IncludeTypeInfoIfNeeded(result, value)

if self.with_metadata:
try:
descriptors, order = self.descriptors_cache[value.__class__.__name__]
except KeyError:
descriptors = {}
order = []
for descriptor, _ in value.ListFields():
order.append(descriptor.name)
descriptors[descriptor.name] = {
"friendly_name": descriptor.friendly_name,
"description": descriptor.description
}

self.descriptors_cache[value.__class__.__name__] = (descriptors,
order)
descriptors = {}
order = []
for descriptor, _ in value.ListSetFields():
order.append(descriptor.name)
descriptors[descriptor.name] = {
"friendly_name": descriptor.friendly_name,
"description": descriptor.description
}

result["metadata"] = descriptors
result["fields_order"] = order
Expand Down
2 changes: 1 addition & 1 deletion gui/http_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def RenderHttpResponse(request):
else:
args = None
elif request.method == "POST":
payload = json.loads(request.raw_post_data)
payload = json.loads(request.body)
args = renderer.args_type(**payload)
else:
raise RuntimeError("Unsupported method: %s." % request.method)
Expand Down
18 changes: 18 additions & 0 deletions gui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "grr",
"author": "Mikhail Bushkov",
"version": "0.1.0",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-jshint": "^0.11.1",
"grunt-html2js": "^0.3.0",
"grunt-karma": "^0.10.1",
"karma": "^0.12.31",
"grunt-closure-tools": "^0.9.8",
"superstartup-closure-compiler": "^0.1.6",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-uglify": "^0.8.1",
"grunt-contrib-watch": "^0.6.1"
}
}
2 changes: 1 addition & 1 deletion gui/plugins/fileview.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class VolumeRenderer(semantic.RDFProtoRenderer):
def Layout(self, request, response):
"""Render the protobuf as a table."""
self.result = []
for descriptor, value in self.proxy.ListFields():
for descriptor, value in self.proxy.ListSetFields():
name = descriptor.name
friendly_name = descriptor.friendly_name or name

Expand Down
24 changes: 12 additions & 12 deletions gui/plugins/searchclient_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ def testUserLabelIsShownAsBootstrapSuccessLabel(self):
token=self.token) as client:
client.AddLabels("foo", owner="test")

self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

self.WaitUntil(self.IsVisible,
"css=tr:contains('C.0000000000000001') "
Expand All @@ -468,18 +468,18 @@ def testSystemLabelIsShownAsRegularBootstrapLabel(self):
token=self.token) as client:
client.AddLabels("bar", owner="GRR")

self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")
self.WaitUntil(self.IsVisible,
"css=tr:contains('C.0000000000000001') "
"span.label:not(.label-success):contains('bar')")

def testLabelButtonIsDisabledByDefault(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")
self.WaitUntil(self.IsVisible,
"css=button[name=AddLabels][disabled]")

def testLabelButtonIsEnabledWhenClientIsSelected(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

self.WaitUntil(self.IsVisible,
"css=button[name=AddLabels][disabled]")
Expand All @@ -489,7 +489,7 @@ def testLabelButtonIsEnabledWhenClientIsSelected(self):
"css=button[name=AddLabels][disabled]")

def testAddClientsLabelsDialogShowsListOfSelectedClients(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

# Select 3 clients and click 'Add Label' button.
self.Click("css=input.client-checkbox["
Expand All @@ -512,7 +512,7 @@ def testAddClientsLabelsDialogShowsListOfSelectedClients(self):
"contains('C.0000000000000007')")

def testAddClientsLabelsDialogShowsErrorWhenAddingLabelWithComma(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

# Select 1 client and click 'Add Label' button.
self.Click("css=input.client-checkbox["
Expand All @@ -530,7 +530,7 @@ def testAddClientsLabelsDialogShowsErrorWhenAddingLabelWithComma(self):
self.WaitUntil(self.IsVisible, "css=div[name=AddClientsLabelsDialog]")

def testLabelIsAppliedCorrectlyViaAddClientsLabelsDialog(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

# Select 1 client and click 'Add Label' button.
self.Click("css=input.client-checkbox["
Expand Down Expand Up @@ -560,7 +560,7 @@ def testLabelIsAppliedCorrectlyViaAddClientsLabelsDialog(self):
"span.label-success:contains('issue 42')")

def testAppliedLabelBecomesSearchableImmediately(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

# Select 1 client and click 'Add Label' button.
self.Click("css=input.client-checkbox["
Expand Down Expand Up @@ -589,7 +589,7 @@ def testAppliedLabelBecomesSearchableImmediately(self):
self.WaitUntil(self.IsTextPresent, "C.0000000000000001")

def testSelectionIsPreservedWhenAddClientsLabelsDialogIsCancelled(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

# Select 1 client and click 'Add Label' button.
self.Click("css=input.client-checkbox["
Expand All @@ -607,7 +607,7 @@ def testSelectionIsPreservedWhenAddClientsLabelsDialogIsCancelled(self):
"client_urn='aff4:/C.0000000000000001']:checked")

def testSelectionIsResetWhenLabelIsAppliedViaAddClientsLabelsDialog(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

# Select 1 client and click 'Add Label' button.
self.Click("css=input.client-checkbox["
Expand All @@ -626,7 +626,7 @@ def testSelectionIsResetWhenLabelIsAppliedViaAddClientsLabelsDialog(self):
"client_urn='aff4:/C.0000000000000001']:not(:checked)")

def testCheckAllCheckboxSelectsAllClients(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

self.WaitUntil(self.IsTextPresent, "C.0000000000000001")

Expand Down Expand Up @@ -670,7 +670,7 @@ def testCheckAllCheckboxSelectsAllClients(self):
"client_urn='aff4:/C.0000000000000007']:not(:checked)")

def testClientsSelectedWithSelectAllAreShownInAddClientsLabelsDialog(self):
self.Open("/#main=HostTable&q=Windows")
self.Open("/#main=HostTable")

self.WaitUntil(self.IsTextPresent, "C.0000000000000001")

Expand Down
2 changes: 1 addition & 1 deletion gui/plugins/semantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def Pre(self, _, value):
def Layout(self, request, response):
"""Render the protobuf as a table."""
self.result = []
for descriptor, value in self.proxy.ListFields():
for descriptor, value in self.proxy.ListSetFields():
name = descriptor.name
friendly_name = descriptor.friendly_name or name

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ describe('clients list', function() {
'type': 'unicode',
'age': 0
}
},
}
},
]
]
}
},
'metadata:clock': {
Expand Down
2 changes: 1 addition & 1 deletion gui/static/angular-components/client/clients-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<th>Last Checkin</th>
</tr>
</thead>
<tbody ng-if="query">
<tbody>
<tr grr-infinite-table grr-api-items-provider
query-params="{query: query}"
url="controller.clientsQueryUrl"
Expand Down
Loading

0 comments on commit 757f5df

Please sign in to comment.