xss test for per-host recent jobs popup

This commit is contained in:
Chris Meyers
2018-02-01 17:34:08 -05:00
parent 290a296f9f
commit aaf87c0c04
3 changed files with 49 additions and 16 deletions

View File

@@ -61,8 +61,21 @@ const getInventory = (namespace = session) => getOrganization(namespace)
.then(organization => getOrCreate('/inventories/', { .then(organization => getOrCreate('/inventories/', {
name: `${namespace}-inventory`, name: `${namespace}-inventory`,
description: namespace, description: namespace,
organization: organization.id organization: organization.id,
})); }).then(inventory => getOrCreate('/hosts/', {
name: `${namespace}-host`,
description: namespace,
inventory: inventory.id,
variables: JSON.stringify({ ansible_connection: 'local' }),
}).then(() => inventory)));
const getHost = (namespace = session) => getInventory(namespace)
.then(inventory => getOrCreate('/hosts/', {
name: `${namespace}-host`,
description: namespace,
inventory: inventory.id,
variables: JSON.stringify({ ansible_connection: 'local' }),
}).then((host) => host));
const getInventoryScript = (namespace = session) => getOrganization(namespace) const getInventoryScript = (namespace = session) => getOrganization(namespace)
.then(organization => getOrCreate('/inventory_scripts/', { .then(organization => getOrCreate('/inventory_scripts/', {
@@ -182,7 +195,7 @@ const waitForJob = endpoint => {
const completed = statuses.indexOf(update.data.status) > -1; const completed = statuses.indexOf(update.data.status) > -1;
if (completed) { if (completed) {
return resolve(); return resolve(update.data);
} }
if (--attempts <= 0) { if (--attempts <= 0) {
@@ -206,6 +219,15 @@ const getUpdatedProject = (namespace = session) => getProject(namespace)
return project; return project;
}); });
const getJob = (namespace = session) => getJobTemplate(namespace)
.then(template => {
const launchURL = template.related.launch;
return post(launchURL, {}).then(response => {
const jobURL = response.data.url;
return waitForJob(jobURL).then(() => response.data);
});
});
const getJobTemplate = (namespace = session) => { const getJobTemplate = (namespace = session) => {
const promises = [ const promises = [
getInventory(namespace), getInventory(namespace),
@@ -302,5 +324,7 @@ module.exports = {
getSmartInventory, getSmartInventory,
getTeam, getTeam,
getUpdatedProject, getUpdatedProject,
getUser getUser,
getJob,
getHost,
}; };

View File

@@ -1,16 +1,5 @@
import _ from 'lodash'; import _ from 'lodash';
import actions from './sections/actions';
import breadcrumb from './sections/breadcrumb';
import createFormSection from './sections/createFormSection';
import createTableSection from './sections/createTableSection';
import header from './sections/header';
import lookupModal from './sections/lookupModal';
import navigation from './sections/navigation';
import pagination from './sections/pagination';
import permissions from './sections/permissions';
import search from './sections/search';
module.exports = { module.exports = {
url () { url () {
return `${this.api.globals.launch_url}/#/jobs`; return `${this.api.globals.launch_url}/#/jobs`;

View File

@@ -1,5 +1,6 @@
import { import {
getAdminMachineCredential, getAdminMachineCredential,
getHost,
getInventory, getInventory,
getInventoryScript, getInventoryScript,
getInventorySource, getInventorySource,
@@ -12,7 +13,7 @@ import {
getSmartInventory, getSmartInventory,
getTeam, getTeam,
getUpdatedProject, getUpdatedProject,
getJobs, getJob,
} from '../fixtures'; } from '../fixtures';
const data = {}; const data = {};
@@ -22,9 +23,11 @@ const pages = {};
module.exports = { module.exports = {
before: (client, done) => { before: (client, done) => {
const namespace = '<div id="xss" class="xss">test</div>'; const namespace = '<div id="xss" class="xss">test</div>';
const namespaceShort = '<div class="xss">t</div>';
const resources = [ const resources = [
getOrganization(namespace).then(obj => { data.organization = obj; }), getOrganization(namespace).then(obj => { data.organization = obj; }),
getHost(namespaceShort).then(obj => { data.host = obj; }),
getInventory(namespace).then(obj => { data.inventory = obj; }), getInventory(namespace).then(obj => { data.inventory = obj; }),
getInventoryScript(namespace).then(obj => { data.inventoryScript = obj; }), getInventoryScript(namespace).then(obj => { data.inventoryScript = obj; }),
getSmartInventory(namespace).then(obj => { data.smartInventory = obj; }), getSmartInventory(namespace).then(obj => { data.smartInventory = obj; }),
@@ -37,6 +40,7 @@ module.exports = {
getTeam(namespace).then(obj => { data.team = obj; }), getTeam(namespace).then(obj => { data.team = obj; }),
getJobTemplateAdmin(namespace).then(obj => { data.user = obj; }), getJobTemplateAdmin(namespace).then(obj => { data.user = obj; }),
getNotificationTemplate(namespace).then(obj => { data.notification = obj; }), getNotificationTemplate(namespace).then(obj => { data.notification = obj; }),
getJob(namespaceShort).then(obj => { data.job = obj; }),
]; ];
Promise.all(resources) Promise.all(resources)
@@ -44,6 +48,7 @@ module.exports = {
pages.organizations = client.page.organizations(); pages.organizations = client.page.organizations();
pages.inventories = client.page.inventories(); pages.inventories = client.page.inventories();
pages.inventoryScripts = client.page.inventoryScripts(); pages.inventoryScripts = client.page.inventoryScripts();
pages.hosts = client.page.hosts();
pages.projects = client.page.projects(); pages.projects = client.page.projects();
pages.credentials = client.page.credentials(); pages.credentials = client.page.credentials();
pages.templates = client.page.templates(); pages.templates = client.page.templates();
@@ -54,6 +59,7 @@ module.exports = {
urls.organization = `${pages.organizations.url()}/${data.organization.id}`; urls.organization = `${pages.organizations.url()}/${data.organization.id}`;
urls.inventory = `${pages.inventories.url()}/inventory/${data.inventory.id}`; urls.inventory = `${pages.inventories.url()}/inventory/${data.inventory.id}`;
urls.hosts = `${pages.hosts.url()}`;
urls.inventoryScript = `${pages.inventoryScripts.url()}/${data.inventoryScript.id}`; urls.inventoryScript = `${pages.inventoryScripts.url()}/${data.inventoryScript.id}`;
urls.inventorySource = `${urls.inventory}/inventory_sources/edit/${data.inventorySource.id}`; urls.inventorySource = `${urls.inventory}/inventory_sources/edit/${data.inventorySource.id}`;
urls.sourceSchedule = `${urls.inventorySource}/schedules/${data.sourceSchedule.id}`; urls.sourceSchedule = `${urls.inventorySource}/schedules/${data.sourceSchedule.id}`;
@@ -681,4 +687,18 @@ module.exports = {
}); });
client.end(); client.end();
}, },
'check host recent jobs popup for unsanitized content': client => {
const itemRow = `#hosts_table tr[id="${data.host.id}"]`;
const itemName = `${itemRow} td[class*="active_failures-"] a`;
const popOver = `${itemRow} td[class*="active_failures-"] div[class*="popover"]`;
client.navigateTo(urls.hosts);
client.click(itemName);
client.expect.element(popOver).present;
client.expect.element('[class=xss]').not.present;
client.end();
},
}; };