From 5ece6502added220692d80feff02f70881f55aec Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Fri, 15 Apr 2022 13:41:05 -0400 Subject: [PATCH] Jira Integration: Cypress e2e tests only (#5055) --- .../integration/all/app/settingsflow.spec.ts | 353 +++++++++++++- cypress/integration/free/admin.spec.ts | 377 ++++++++++++++- cypress/integration/premium/admin.spec.ts | 434 ++++++++++++++++-- .../integration/premium/maintainer.spec.ts | 11 +- .../OperatingSystems/OperatingSystems.tsx | 1 - .../ManageAutomationsModal.tsx | 5 + 6 files changed, 1135 insertions(+), 46 deletions(-) diff --git a/cypress/integration/all/app/settingsflow.spec.ts b/cypress/integration/all/app/settingsflow.spec.ts index 2295b11994..ed16b81415 100644 --- a/cypress/integration/all/app/settingsflow.spec.ts +++ b/cypress/integration/all/app/settingsflow.spec.ts @@ -1,3 +1,230 @@ +const getConfig = { + org_info: { + org_name: "Fleet Test", + org_logo_url: "", + }, + server_settings: { + server_url: "https://localhost:8642", + live_query_disabled: false, + enable_analytics: true, + deferred_save_host: false, + }, + smtp_settings: { + enable_smtp: false, + configured: false, + sender_address: "", + server: "", + port: 587, + authentication_type: "authtype_username_password", + user_name: "", + password: "", + enable_ssl_tls: true, + authentication_method: "authmethod_plain", + domain: "", + verify_ssl_certs: true, + enable_start_tls: true, + }, + host_expiry_settings: { + host_expiry_enabled: true, + host_expiry_window: 9, + }, + host_settings: { + enable_host_users: true, + enable_software_inventory: true, + }, + agent_options: { + config: { + options: { + logger_plugin: "tls", + pack_delimiter: "/", + logger_tls_period: 10, + distributed_plugin: "tls", + disable_distributed: false, + logger_tls_endpoint: "/api/osquery/log", + distributed_interval: 10, + distributed_tls_max_attempts: 3, + }, + decorators: { + load: [ + "SELECT uuid AS host_uuid FROM system_info;", + "SELECT hostname AS hostname FROM system_info;", + ], + }, + }, + overrides: {}, + }, + sso_settings: { + entity_id: "", + issuer_uri: "", + idp_image_url: "", + metadata: "", + metadata_url: "", + idp_name: "", + enable_sso: false, + enable_sso_idp_login: false, + }, + vulnerability_settings: { + databases_path: "", + }, + webhook_settings: { + host_status_webhook: { + enable_host_status_webhook: false, + destination_url: "", + host_percentage: 0, + days_count: 0, + }, + failing_policies_webhook: { + enable_failing_policies_webhook: true, + destination_url: "ok.com", + policy_ids: [5, 10], + host_batch_size: 0, + }, + vulnerabilities_webhook: { + enable_vulnerabilities_webhook: true, + destination_url: "", + host_batch_size: 0, + }, + interval: "24h0m0s", + }, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + update_interval: { + osquery_detail: 3600000000000, + osquery_policy: 3600000000000, + }, + vulnerabilities: { + databases_path: "/tmp/vulndbs", + periodicity: 3600000000000, + cpe_database_url: "", + cve_feed_prefix_url: "", + current_instance_checks: "auto", + disable_data_sync: false, + recent_vulnerability_max_age: 2592000000000000, + }, + license: { + tier: "premium", + organization: "development-only", + device_count: 100, + expiration: "2022-06-30T20:00:00-04:00", + note: "for development only", + }, + logging: { + debug: false, + json: false, + result: { + plugin: "filesystem", + config: { + status_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", + result_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", + enable_log_rotation: false, + enable_log_compression: false, + }, + }, + status: { + plugin: "filesystem", + config: { + status_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", + result_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", + enable_log_rotation: false, + enable_log_compression: false, + }, + }, + }, +}; + +const createConfig = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira@example.com", + api_token: "jira123", + project_key: "PROJECT", + enable_software_vulnerabilities: false, + }, + ], + }, +}; + +const editConfig = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira0@example.com", + api_token: "jira0123", + project_key: "PROJECT 0", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, +}; + +const deleteConfig = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, +}; + describe("App settings flow", () => { before(() => { Cypress.session.clearAllSavedSessions(); @@ -9,7 +236,7 @@ describe("App settings flow", () => { cy.logout(); }); - describe("Teams settings page", () => { + describe("Organization settings page", () => { beforeEach(() => { cy.loginWithCySession(); cy.visit("/settings/organization"); @@ -200,4 +427,128 @@ describe("App settings flow", () => { }); }); }); + + describe("Integrations settings page (empty)", () => { + beforeEach(() => { + cy.loginWithCySession(); + cy.visit("/settings/integrations"); + }); + it("creates a new jira integration", () => { + cy.getAttached(".no-integrations__create-button").click(); + cy.getAttached("#url").click().type("https://fleetdm.atlassian.com"); + cy.getAttached("#username").click().type("jira@example.com"); + cy.getAttached("#apiToken").click().type("jira123"); + cy.getAttached("#projectKey").click().type("PROJECT"); + cy.intercept("PATCH", "/api/latest/fleet/config", createConfig).as( + "createIntegration" + ); + cy.intercept("GET", "/api/latest/fleet/config", createConfig).as( + "createdIntegration" + ); + cy.findByRole("button", { name: /save/i }).click(); + cy.wait("@createIntegration").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + }); + cy.wait("@createdIntegration").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + }); + cy.findByText(/successfully added/i).should("exist"); + cy.getAttached(".table-container").within(() => { + cy.findByText(/fleetdm.atlassian.com - PROJECT/i).should("exist"); + }); + }); + }); + + describe("Integrations settings page (seeded)", () => { + beforeEach(() => { + Cypress.session.clearAllSavedSessions(); + cy.setup(); + cy.loginWithCySession(); + cy.viewport(1200, 660); + cy.intercept("GET", "/api/latest/fleet/config", getConfig).as( + "getIntegrations" + ); + cy.visit("/settings/integrations"); + cy.wait("@getIntegrations").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + }); + }); + it("edits jira integration", () => { + cy.getAttached("tbody>tr") + .should("have.length", 3) + .eq(1) + .within(() => { + cy.findByText(/action/i).click(); + cy.findByText(/edit/i).click(); + }); + cy.findByLabelText(/jira site url/i) + .clear() + .type("https://fleetdm.atlassian.com"); + cy.findByLabelText(/jira username/i) + .clear() + .type("jira0@example.com"); + cy.findByLabelText(/jira api token/i) + .clear() + .type("jira0123"); + cy.findByLabelText(/jira project key/i) + .clear() + .type("PROJECT 0"); + cy.intercept("PATCH", "/api/latest/fleet/config", editConfig).as( + "editIntegration" + ); + cy.intercept("GET", "/api/latest/fleet/config", editConfig).as( + "editedIntegration" + ); + cy.getAttached(".integration-form__btn-wrap") + .contains("button", /save/i) + .click(); + cy.wait("@editIntegration").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + }); + cy.wait("@editedIntegration").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + cy.findByText(/successfully edited/i).should("exist"); + cy.getAttached("tbody>tr") + .should("have.length", 3) + .eq(0) + .within(() => { + cy.findByText(/fleetdm.atlassian.com - project 0/i).should("exist"); + }); + }); + }); + it("deletes jira integration", () => { + cy.getAttached("tbody>tr") + .eq(1) + .within(() => { + cy.findByText(/project 2/i).should("exist"); + cy.findByText(/action/i).click(); + cy.findByText(/delete/i).click(); + }); + cy.intercept("PATCH", "/api/latest/fleet/config", deleteConfig).as( + "deleteIntegration" + ); + cy.intercept("GET", "/api/latest/fleet/config", deleteConfig).as( + "deletedIntegration" + ); + cy.getAttached(".delete-integration-modal__btn-wrap") + .contains("button", /delete/i) + .click(); + cy.wait("@deleteIntegration").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + }); + cy.wait("@deletedIntegration").then((configStub) => { + cy.log(JSON.stringify(configStub)); + console.log(JSON.stringify(configStub)); + }); + cy.findByText(/successfully deleted/i).should("exist"); + cy.getAttached("tbody>tr").should("have.length", 2); + cy.findByText(/project 2/i).should("not.exist"); + }); + }); }); diff --git a/cypress/integration/free/admin.spec.ts b/cypress/integration/free/admin.spec.ts index 71ce3dafa6..043a42234f 100644 --- a/cypress/integration/free/admin.spec.ts +++ b/cypress/integration/free/admin.spec.ts @@ -1,3 +1,269 @@ +const getConfig = { + org_info: { + org_name: "Fleet Test", + org_logo_url: "", + }, + server_settings: { + server_url: "https://localhost:8642", + live_query_disabled: false, + enable_analytics: true, + deferred_save_host: false, + }, + smtp_settings: { + enable_smtp: false, + configured: false, + sender_address: "", + server: "", + port: 587, + authentication_type: "authtype_username_password", + user_name: "", + password: "", + enable_ssl_tls: true, + authentication_method: "authmethod_plain", + domain: "", + verify_ssl_certs: true, + enable_start_tls: true, + }, + host_expiry_settings: { + host_expiry_enabled: true, + host_expiry_window: 9, + }, + host_settings: { + enable_host_users: true, + enable_software_inventory: true, + }, + agent_options: { + config: { + options: { + logger_plugin: "tls", + pack_delimiter: "/", + logger_tls_period: 10, + distributed_plugin: "tls", + disable_distributed: false, + logger_tls_endpoint: "/api/osquery/log", + distributed_interval: 10, + distributed_tls_max_attempts: 3, + }, + decorators: { + load: [ + "SELECT uuid AS host_uuid FROM system_info;", + "SELECT hostname AS hostname FROM system_info;", + ], + }, + }, + overrides: {}, + }, + sso_settings: { + entity_id: "", + issuer_uri: "", + idp_image_url: "", + metadata: "", + metadata_url: "", + idp_name: "", + enable_sso: false, + enable_sso_idp_login: false, + }, + vulnerability_settings: { + databases_path: "", + }, + webhook_settings: { + host_status_webhook: { + enable_host_status_webhook: false, + destination_url: "", + host_percentage: 0, + days_count: 0, + }, + failing_policies_webhook: { + enable_failing_policies_webhook: true, + destination_url: "ok.com", + policy_ids: [5, 10], + host_batch_size: 0, + }, + vulnerabilities_webhook: { + enable_vulnerabilities_webhook: false, + destination_url: "", + host_batch_size: 0, + }, + interval: "24h0m0s", + }, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: true, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + update_interval: { + osquery_detail: 3600000000000, + osquery_policy: 3600000000000, + }, + vulnerabilities: { + databases_path: "/tmp/vulndbs", + periodicity: 3600000000000, + cpe_database_url: "", + cve_feed_prefix_url: "", + current_instance_checks: "auto", + disable_data_sync: false, + recent_vulnerability_max_age: 2592000000000000, + }, + license: { + tier: "premium", + organization: "development-only", + device_count: 100, + expiration: "2022-06-30T20:00:00-04:00", + note: "for development only", + }, + logging: { + debug: false, + json: false, + result: { + plugin: "filesystem", + config: { + status_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", + result_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", + enable_log_rotation: false, + enable_log_compression: false, + }, + }, + status: { + plugin: "filesystem", + config: { + status_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", + result_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", + enable_log_rotation: false, + enable_log_compression: false, + }, + }, + }, +}; + +const enableWebhook = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + webhook_settings: { + vulnerabilities_webhook: { + destination_url: "www.foo.com/bar", + enable_vulnerabilities_webhook: true, + }, + }, +}; + +const enableIntegration = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: true, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + webhook_settings: { + vulnerabilities_webhook: { + destination_url: "www.foo.com/bar", + enable_vulnerabilities_webhook: false, + }, + }, +}; + +const disableAutomations = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + webhook_settings: { + vulnerabilities_webhook: { + destination_url: "www.foo.com/bar", + enable_vulnerabilities_webhook: false, + }, + }, +}; + describe( "Free tier - Admin user", { @@ -18,7 +284,6 @@ describe( cy.logout(); cy.stopDockerHost(); }); - describe("Navigation", () => { beforeEach(() => { cy.loginWithCySession("anna@organization.com", "user123#"); @@ -195,20 +460,37 @@ describe( describe("Manage software page", () => { beforeEach(() => { cy.loginWithCySession("anna@organization.com", "user123#"); + cy.intercept("GET", "/api/latest/fleet/config", getConfig).as( + "getIntegrations" + ); cy.visit("/software/manage"); + cy.wait("@getIntegrations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); }); - it("allows global admin to create webhook software vulnerability automation", () => { + it("allows admin to create webhook software vulnerability automation", () => { cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); + cy.findByRole("button", { name: /manage automations/i }).click(); }); cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider").click(); cy.getAttached(".fleet-slider").click(); cy.getAttached("#webhook-radio-btn").next().click(); }); cy.getAttached("#webhook-url").click().type("www.foo.com/bar"); + cy.intercept("PATCH", "/api/latest/fleet/config", enableWebhook).as( + "createWebhook" + ); + cy.intercept("GET", "/api/latest/fleet/config", enableWebhook).as( + "createdWebhook" + ); cy.findByRole("button", { name: /^Save$/ }).click(); + cy.wait("@createWebhook").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.wait("@createdWebhook").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); // Confirm manage automations webhook was added successfully cy.findByText(/updated vulnerability automations/i).should("exist"); cy.getAttached(".button-wrap").within(() => { @@ -221,6 +503,86 @@ describe( cy.getAttached("#webhook-url").should("exist"); }); }); + it("allows admin to create jira integration software vulnerability automation", () => { + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider").click(); + cy.getAttached(".fleet-slider").click(); + cy.getAttached("#ticket-radio-btn").next().click(); + cy.findByText(/project 1/i).click(); + cy.findByText(/project 2/i).click(); + }); + cy.intercept("PATCH", "/api/latest/fleet/config", enableIntegration).as( + "enableIntegration" + ); + cy.intercept("GET", "/api/latest/fleet/config", enableIntegration).as( + "enabledIntegration" + ); + cy.findByRole("button", { name: /^Save$/ }).click(); + cy.wait("@enableIntegration").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.wait("@enabledIntegration").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + // Confirm jira integration was added successfully + cy.findByText(/updated vulnerability automations/i).should("exist"); + cy.intercept("GET", "/api/latest/fleet/config", enableIntegration).as( + "getIntegrations" + ); + cy.visit("/software/manage"); + cy.wait("@getIntegrations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.getAttached(".button-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider--active").should("exist"); + cy.findByText(/project 2/i).should("exist"); + }); + }); + it("allows admin to disable software vulnerability automation", () => { + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider").click(); + }); + cy.intercept( + "PATCH", + "/api/latest/fleet/config", + disableAutomations + ).as("disableAutomations"); + cy.intercept("GET", "/api/latest/fleet/config", disableAutomations).as( + "disabledAutomations" + ); + cy.findByRole("button", { name: /^Save$/ }).click(); + cy.wait("@disableAutomations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.wait("@disabledAutomations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + // Confirm integration was disabled successfully + cy.findByText(/updated vulnerability automations/i).should("exist"); + cy.getAttached(".button-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.findByText(/vulnerability automations disabled/i).should("exist"); + }); + }); }); describe("Query pages", () => { beforeEach(() => { @@ -327,9 +689,12 @@ describe( it("hides access team settings", () => { cy.findByText(/teams/i).should("not.exist"); }); - it("allows admin to access other settings", () => { + it("allows admin to access integrations and users settings", () => { cy.getAttached(".react-tabs").within(() => { cy.findByText(/organization settings/i).should("exist"); + cy.findByText(/integrations/i).click(); + }); + cy.getAttached(".react-tabs").within(() => { cy.findByText(/users/i).click(); }); }); diff --git a/cypress/integration/premium/admin.spec.ts b/cypress/integration/premium/admin.spec.ts index b20662e6fd..d6c508223e 100644 --- a/cypress/integration/premium/admin.spec.ts +++ b/cypress/integration/premium/admin.spec.ts @@ -1,3 +1,269 @@ +const getConfig = { + org_info: { + org_name: "Fleet Test", + org_logo_url: "", + }, + server_settings: { + server_url: "https://localhost:8642", + live_query_disabled: false, + enable_analytics: true, + deferred_save_host: false, + }, + smtp_settings: { + enable_smtp: false, + configured: false, + sender_address: "", + server: "", + port: 587, + authentication_type: "authtype_username_password", + user_name: "", + password: "", + enable_ssl_tls: true, + authentication_method: "authmethod_plain", + domain: "", + verify_ssl_certs: true, + enable_start_tls: true, + }, + host_expiry_settings: { + host_expiry_enabled: true, + host_expiry_window: 9, + }, + host_settings: { + enable_host_users: true, + enable_software_inventory: true, + }, + agent_options: { + config: { + options: { + logger_plugin: "tls", + pack_delimiter: "/", + logger_tls_period: 10, + distributed_plugin: "tls", + disable_distributed: false, + logger_tls_endpoint: "/api/osquery/log", + distributed_interval: 10, + distributed_tls_max_attempts: 3, + }, + decorators: { + load: [ + "SELECT uuid AS host_uuid FROM system_info;", + "SELECT hostname AS hostname FROM system_info;", + ], + }, + }, + overrides: {}, + }, + sso_settings: { + entity_id: "", + issuer_uri: "", + idp_image_url: "", + metadata: "", + metadata_url: "", + idp_name: "", + enable_sso: false, + enable_sso_idp_login: false, + }, + vulnerability_settings: { + databases_path: "", + }, + webhook_settings: { + host_status_webhook: { + enable_host_status_webhook: false, + destination_url: "", + host_percentage: 0, + days_count: 0, + }, + failing_policies_webhook: { + enable_failing_policies_webhook: true, + destination_url: "ok.com", + policy_ids: [5, 10], + host_batch_size: 0, + }, + vulnerabilities_webhook: { + enable_vulnerabilities_webhook: false, + destination_url: "", + host_batch_size: 0, + }, + interval: "24h0m0s", + }, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: true, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + update_interval: { + osquery_detail: 3600000000000, + osquery_policy: 3600000000000, + }, + vulnerabilities: { + databases_path: "/tmp/vulndbs", + periodicity: 3600000000000, + cpe_database_url: "", + cve_feed_prefix_url: "", + current_instance_checks: "auto", + disable_data_sync: false, + recent_vulnerability_max_age: 2592000000000000, + }, + license: { + tier: "premium", + organization: "development-only", + device_count: 100, + expiration: "2022-06-30T20:00:00-04:00", + note: "for development only", + }, + logging: { + debug: false, + json: false, + result: { + plugin: "filesystem", + config: { + status_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", + result_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", + enable_log_rotation: false, + enable_log_compression: false, + }, + }, + status: { + plugin: "filesystem", + config: { + status_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_status", + result_log_file: + "/var/folders/xh/bxm1d2615tv3vrg4zrxq540h0000gn/T/osquery_result", + enable_log_rotation: false, + enable_log_compression: false, + }, + }, + }, +}; + +const enableWebhook = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + webhook_settings: { + vulnerabilities_webhook: { + destination_url: "www.foo.com/bar", + enable_vulnerabilities_webhook: true, + }, + }, +}; + +const enableIntegration = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: true, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + webhook_settings: { + vulnerabilities_webhook: { + destination_url: "www.foo.com/bar", + enable_vulnerabilities_webhook: false, + }, + }, +}; + +const disableAutomations = { + ...getConfig, + integrations: { + jira: [ + { + url: "https://fleetdm.atlassian.com", + username: "jira1@example.com", + api_token: "jira123", + project_key: "PROJECT 1", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira2@example.com", + api_token: "jira123", + project_key: "PROJECT 2", + enable_software_vulnerabilities: false, + }, + { + url: "https://fleetdm.atlassian.com", + username: "jira3@example.com", + api_token: "jira123", + project_key: "PROJECT 3", + enable_software_vulnerabilities: false, + }, + ], + }, + webhook_settings: { + vulnerabilities_webhook: { + destination_url: "www.foo.com/bar", + enable_vulnerabilities_webhook: false, + }, + }, +}; + describe("Premium tier - Global Admin user", () => { before(() => { Cypress.session.clearAllSavedSessions(); @@ -71,6 +337,139 @@ describe("Premium tier - Global Admin user", () => { .click(); }); }); + describe("Manage software page", () => { + beforeEach(() => { + cy.intercept("GET", "/api/latest/fleet/config", getConfig).as( + "getIntegrations" + ); + cy.visit("/software/manage"); + cy.wait("@getIntegrations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + }); + it("allows admin to create webhook software vulnerability automation", () => { + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.findByRole("button", { name: /manage automations/i }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider").click(); + cy.getAttached(".fleet-slider").click(); + cy.getAttached("#webhook-radio-btn").next().click(); + }); + cy.getAttached("#webhook-url").click().type("www.foo.com/bar"); + cy.intercept("PATCH", "/api/latest/fleet/config", enableWebhook).as( + "createWebhook" + ); + cy.intercept("GET", "/api/latest/fleet/config", enableWebhook).as( + "createdWebhook" + ); + cy.findByRole("button", { name: /^Save$/ }).click(); + cy.wait("@createWebhook").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.wait("@createdWebhook").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + // Confirm manage automations webhook was added successfully + cy.findByText(/updated vulnerability automations/i).should("exist"); + cy.getAttached(".button-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider--active").should("exist"); + cy.getAttached("#webhook-url").should("exist"); + }); + }); + it("allows admin to create jira integration software vulnerability automation", () => { + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider").click(); + cy.getAttached(".fleet-slider").click(); + cy.getAttached("#ticket-radio-btn").next().click(); + cy.findByText(/project 1/i).click(); + cy.findByText(/project 2/i).click(); + }); + cy.intercept("PATCH", "/api/latest/fleet/config", enableIntegration).as( + "enableIntegration" + ); + cy.intercept("GET", "/api/latest/fleet/config", enableIntegration).as( + "enabledIntegration" + ); + cy.findByRole("button", { name: /^Save$/ }).click(); + cy.wait("@enableIntegration").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.wait("@enabledIntegration").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + // Confirm jira integration was added successfully + cy.findByText(/updated vulnerability automations/i).should("exist"); + cy.intercept("GET", "/api/latest/fleet/config", enableIntegration).as( + "getIntegrations" + ); + cy.visit("/software/manage"); + cy.wait("@getIntegrations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.getAttached(".button-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider--active").should("exist"); + cy.findByText(/project 2/i).should("exist"); + }); + }); + it("allows admin to disable software vulnerability automation", () => { + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.getAttached(".fleet-slider").click(); + }); + cy.intercept("PATCH", "/api/latest/fleet/config", disableAutomations).as( + "disableAutomations" + ); + cy.intercept("GET", "/api/latest/fleet/config", disableAutomations).as( + "disabledAutomations" + ); + cy.findByRole("button", { name: /^Save$/ }).click(); + cy.wait("@disableAutomations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + cy.wait("@disabledAutomations").then((configStub) => { + console.log(JSON.stringify(configStub)); + }); + // Confirm integration was disabled successfully + cy.findByText(/updated vulnerability automations/i).should("exist"); + cy.getAttached(".button-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).click(); + }); + cy.getAttached(".manage-automations-modal").within(() => { + cy.findByText(/vulnerability automations disabled/i).should("exist"); + }); + }); + it("hides manage automations button since all teams not selected", () => { + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.getAttached(".Select").within(() => { + cy.findByText(/all teams/i).click(); + cy.findByText(/apples/i).click(); + }); + cy.findByText(/manage automations/i).should("not.exist"); + }); + }); + }); describe("Host details page", () => { beforeEach(() => cy.visit("hosts/2")); it("allows global admin to transfer host to an existing team", () => { @@ -113,40 +512,7 @@ describe("Premium tier - Global Admin user", () => { }); }); }); - describe("Manage software page", () => { - beforeEach(() => cy.visit("/software/manage")); - it("allows global admin to create webhook software vulnerability automation", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.findByRole("button", { name: /manage automations/i }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider").click(); - cy.getAttached("#webhook-radio-btn").next().click(); - }); - cy.getAttached("#webhook-url").click().type("www.foo.com/bar"); - cy.findByRole("button", { name: /^Save$/ }).click(); - // Confirm manage automations webhook was added successfully - cy.findByText(/updated vulnerability automations/i).should("exist"); - cy.getAttached(".button-wrap").within(() => { - cy.findByRole("button", { - name: /manage automations/i, - }).click(); - }); - cy.getAttached(".manage-automations-modal").within(() => { - cy.getAttached(".fleet-slider--active").should("exist"); - cy.getAttached("#webhook-url").should("exist"); - }); - }); - it("hides manage automations button since all teams not selected", () => { - cy.getAttached(".manage-software-page__header-wrap").within(() => { - cy.getAttached(".Select").within(() => { - cy.findByText(/all teams/i).click(); - cy.findByText(/apples/i).click(); - }); - cy.findByText(/manage automations/i).should("not.exist"); - }); - }); - }); + describe("Query pages", () => { beforeEach(() => cy.visit("/queries/manage")); it("allows global admin to select teams targets for query", () => { diff --git a/cypress/integration/premium/maintainer.spec.ts b/cypress/integration/premium/maintainer.spec.ts index b4abf5eeea..4c88e81feb 100644 --- a/cypress/integration/premium/maintainer.spec.ts +++ b/cypress/integration/premium/maintainer.spec.ts @@ -201,14 +201,17 @@ describe("Premium tier - Maintainer user", () => { }); describe("Manage software page", () => { beforeEach(() => cy.visit("/software/manage")); - it("allows global maintainer to click 'Manage automations' button", () => { - it("manages software automations when all teams selected", () => { + it("should restrict global maintainer from 'Manage automations' button", () => { + it("hides manages software automations when all teams selected", () => { cy.getAttached(".manage-software-page__header-wrap").within(() => { cy.getAttached(".Select").within(() => { cy.findByText(/all teams/i).should("exist"); }); - cy.findByRole("button", { name: /manage automations/i }).click(); - cy.findByRole("button", { name: /cancel/i }).click(); + cy.getAttached(".manage-software-page__header-wrap").within(() => { + cy.findByRole("button", { + name: /manage automations/i, + }).should("not.exist"); + }); }); }); it("hides manage automations button when all teams not selected", () => { diff --git a/frontend/pages/Homepage/cards/OperatingSystems/OperatingSystems.tsx b/frontend/pages/Homepage/cards/OperatingSystems/OperatingSystems.tsx index 36ec28543d..90e9e04ac3 100644 --- a/frontend/pages/Homepage/cards/OperatingSystems/OperatingSystems.tsx +++ b/frontend/pages/Homepage/cards/OperatingSystems/OperatingSystems.tsx @@ -88,7 +88,6 @@ const OperatingSystems = ({ // Renders opaque information as host information is loading const opacity = showOperatingSystemsUI ? { opacity: 1 } : { opacity: 0 }; - console.log("teamId: ", currentTeamId); // TODO: Error states? Product says if any card on homepage fails the whole page should 500. Is // that really what we want to happen? Do we want that to happen always? What if just one card diff --git a/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx b/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx index 85af29e7f8..5eb777ea13 100644 --- a/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx +++ b/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx @@ -88,6 +88,11 @@ const ManageAutomationsModal = ({ selectedIntegration, setSelectedIntegration, ] = useState(); + useDeepEffect(() => { + setSoftwareAutomationsEnabled( + softwareVulnerabilityAutomationEnabled || false + ); + }, [softwareVulnerabilityAutomationEnabled]); useDeepEffect(() => { if (destinationUrl) {