diff --git a/hqu/hqapi1/app/AlertController.groovy b/hqu/hqapi1/app/AlertController.groovy index dc5f3528..b6fc224c 100644 --- a/hqu/hqapi1/app/AlertController.groovy +++ b/hqu/hqapi1/app/AlertController.groovy @@ -218,6 +218,33 @@ public class AlertController extends ApiController { } } + private canManageAlerts(resource) { + // TODO: Fix AlertManager to handle permissions + def appdefResource + // TODO: Platform/Server/Service have different modifyAlert operations + def operation + if (resource.isPlatform()) { + operation = "modifyAlerts" + appdefResource = resource.toPlatform() + } else if (resource.isServer()) { + operation = "modifyAlerts" + appdefResource = resource.toServer() + } else if (resource.isService()) { + operation = "manageAlerts" + appdefResource = resource.toService() + } else { + log.warn("Unhandled resource to canManageAlerts: " + resource.name) + return false + } + + try { + appdefResource.checkPerms(operation:operation, user:user) + return true + } catch (Exception e) { + return false + } + } + def fix(params) { def ids = params.get("id")*.toInteger() def failureXml = null @@ -232,6 +259,8 @@ public class AlertController extends ApiController { if (!alert) { failureXml = getFailureXML(ErrorCode.OBJECT_NOT_FOUND, "Unable to find alert with id = " + id) + } else if (!canManageAlerts(alert.definition.resource)) { + failureXml = getFailureXML(ErrorCode.PERMISSION_DENIED) } else { alerts << alert } diff --git a/src/org/hyperic/hq/hqapi1/test/AlertAck_test.java b/src/org/hyperic/hq/hqapi1/test/AlertAck_test.java index b1ca0c97..5f60a4b5 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertAck_test.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertAck_test.java @@ -4,6 +4,7 @@ import org.hyperic.hq.hqapi1.types.AlertsResponse; import org.hyperic.hq.hqapi1.types.Alert; import org.hyperic.hq.hqapi1.types.StatusResponse; +import org.hyperic.hq.hqapi1.types.Resource; import org.hyperic.hq.hqapi1.AlertApi; public class AlertAck_test extends AlertTestBase { @@ -13,10 +14,11 @@ public AlertAck_test(String name) { } public void testAckAlert() throws Exception { - AlertDefinition d = generateAlerts(); + Resource platform = getLocalPlatformResource(false, false); + AlertDefinition d = generateAlerts(platform); AlertApi api = getAlertApi(); - AlertsResponse response = api.findAlerts(0, System.currentTimeMillis(), + AlertsResponse response = api.findAlerts(platform, 0, System.currentTimeMillis(), 10, 1, false, false); hqAssertSuccess(response); assertTrue(response.getAlert().size() <= 10); diff --git a/src/org/hyperic/hq/hqapi1/test/AlertDelete_test.java b/src/org/hyperic/hq/hqapi1/test/AlertDelete_test.java index f3a66634..47d1190d 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertDelete_test.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertDelete_test.java @@ -4,6 +4,7 @@ import org.hyperic.hq.hqapi1.types.AlertsResponse; import org.hyperic.hq.hqapi1.types.Alert; import org.hyperic.hq.hqapi1.types.StatusResponse; +import org.hyperic.hq.hqapi1.types.Resource; import org.hyperic.hq.hqapi1.AlertApi; public class AlertDelete_test extends AlertTestBase { @@ -13,10 +14,11 @@ public AlertDelete_test(String name) { } public void testDeleteAlert() throws Exception { - AlertDefinition d = generateAlerts(); + Resource platform = getLocalPlatformResource(false, false); + AlertDefinition d = generateAlerts(platform); AlertApi api = getAlertApi(); - AlertsResponse response = api.findAlerts(0, System.currentTimeMillis(), + AlertsResponse response = api.findAlerts(platform, 0, System.currentTimeMillis(), 10, 1, false, false); hqAssertSuccess(response); assertTrue(response.getAlert().size() <= 10); diff --git a/src/org/hyperic/hq/hqapi1/test/AlertFindByResource_test.java b/src/org/hyperic/hq/hqapi1/test/AlertFindByResource_test.java index 3db59b5e..a03ae171 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertFindByResource_test.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertFindByResource_test.java @@ -15,7 +15,7 @@ public AlertFindByResource_test(String name) { public void testFindValid() throws Exception { Resource r = getLocalPlatformResource(false, false); - AlertDefinition d = generateAlerts(); + AlertDefinition d = generateAlerts(r); AlertApi api = getAlertApi(); diff --git a/src/org/hyperic/hq/hqapi1/test/AlertFind_test.java b/src/org/hyperic/hq/hqapi1/test/AlertFind_test.java index 0db2185c..fa32fde3 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertFind_test.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertFind_test.java @@ -5,6 +5,7 @@ import org.hyperic.hq.hqapi1.types.AlertsResponse; import org.hyperic.hq.hqapi1.types.StatusResponse; import org.hyperic.hq.hqapi1.types.Alert; +import org.hyperic.hq.hqapi1.types.Resource; public class AlertFind_test extends AlertTestBase { @@ -13,7 +14,8 @@ public AlertFind_test(String name) { } public void testFindValid() throws Exception { - AlertDefinition d = generateAlerts(); + Resource platform = getLocalPlatformResource(false, false); + AlertDefinition d = generateAlerts(platform); AlertApi api = getAlertApi(); AlertsResponse response = api.findAlerts(0, System.currentTimeMillis(), diff --git a/src/org/hyperic/hq/hqapi1/test/AlertFix_test.java b/src/org/hyperic/hq/hqapi1/test/AlertFix_test.java index 6ee6fdff..7d6c5310 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertFix_test.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertFix_test.java @@ -4,7 +4,14 @@ import org.hyperic.hq.hqapi1.types.AlertsResponse; import org.hyperic.hq.hqapi1.types.StatusResponse; import org.hyperic.hq.hqapi1.types.Alert; +import org.hyperic.hq.hqapi1.types.User; +import org.hyperic.hq.hqapi1.types.Resource; +import org.hyperic.hq.hqapi1.types.ResourcePrototypeResponse; +import org.hyperic.hq.hqapi1.types.ResourcesResponse; import org.hyperic.hq.hqapi1.AlertApi; +import org.hyperic.hq.hqapi1.ResourceApi; + +import java.util.List; public class AlertFix_test extends AlertTestBase { @@ -13,7 +20,8 @@ public AlertFix_test(String name) { } public void testFixAlert() throws Exception { - AlertDefinition d = generateAlerts(); + Resource platform = getLocalPlatformResource(false, false); + AlertDefinition d = generateAlerts(platform); AlertApi api = getAlertApi(); AlertsResponse response = api.findAlerts(0, System.currentTimeMillis(), @@ -40,6 +48,140 @@ public void testFixAlert() throws Exception { hqAssertSuccess(deleteResponse); } + public void testFixPlatformAlertNoPermission() throws Exception { + Resource platform = getLocalPlatformResource(false, false); + AlertDefinition d = generateAlerts(platform); + AlertApi api = getAlertApi(); + + AlertsResponse response = api.findAlerts(platform, 0, System.currentTimeMillis(), + 10, 1, false, false); + hqAssertSuccess(response); + assertTrue(response.getAlert().size() <= 10); + assertTrue(response.getAlert().size() > 0); + + for (Alert a : response.getAlert()) { + validateAlert(a); + } + + List users = createTestUsers(1); + User unprivUser = users.get(0); + AlertApi apiUnpriv = getApi(unprivUser.getName(), TESTUSER_PASSWORD).getAlertApi(); + + // Test marking fixed with an unprivlidged user + Alert a = response.getAlert().get(0); + + StatusResponse fixResponse = apiUnpriv.fixAlert(a.getId()); + hqAssertFailurePermissionDenied(fixResponse); + + // TODO: Valididate fix flag was set? Will require a getById API. + + // Cleanup + StatusResponse deleteResponse = getApi(). + getAlertDefinitionApi().deleteAlertDefinition(d.getId()); + hqAssertSuccess(deleteResponse); + deleteTestUsers(users); + } + + public void testFixServerAlertNoPermission() throws Exception { + ResourceApi rApi = getApi().getResourceApi(); + AlertApi api = getAlertApi(); + + ResourcePrototypeResponse protoResponse = + rApi.getResourcePrototype("HQ Agent"); + hqAssertSuccess(protoResponse); + + ResourcesResponse resourcesResponse = + rApi.getResources(protoResponse.getResourcePrototype(), + false, false); + hqAssertSuccess(resourcesResponse); + + assertTrue("No resources of type " + + protoResponse.getResourcePrototype().getName() + + " could be found!", resourcesResponse.getResource().size() > 0); + + Resource server = resourcesResponse.getResource().get(0); + + AlertDefinition d = generateAlerts(server); + + AlertsResponse response = api.findAlerts(server, 0, System.currentTimeMillis(), + 10, 1, false, false); + hqAssertSuccess(response); + assertTrue(response.getAlert().size() <= 10); + assertTrue(response.getAlert().size() > 0); + + for (Alert a : response.getAlert()) { + validateAlert(a); + } + + List users = createTestUsers(1); + User unprivUser = users.get(0); + AlertApi apiUnpriv = getApi(unprivUser.getName(), TESTUSER_PASSWORD).getAlertApi(); + + // Test marking fixed with an unprivlidged user + Alert a = response.getAlert().get(0); + + StatusResponse fixResponse = apiUnpriv.fixAlert(a.getId()); + hqAssertFailurePermissionDenied(fixResponse); + + // TODO: Valididate fix flag was set? Will require a getById API. + + // Cleanup + StatusResponse deleteResponse = getApi(). + getAlertDefinitionApi().deleteAlertDefinition(d.getId()); + hqAssertSuccess(deleteResponse); + deleteTestUsers(users); + } + + public void testFixServiceAlertNoPermission() throws Exception { + ResourceApi rApi = getApi().getResourceApi(); + AlertApi api = getAlertApi(); + + ResourcePrototypeResponse protoResponse = + rApi.getResourcePrototype("FileServer Mount"); + hqAssertSuccess(protoResponse); + + ResourcesResponse resourcesResponse = + rApi.getResources(protoResponse.getResourcePrototype(), + false, false); + hqAssertSuccess(resourcesResponse); + + assertTrue("No resources of type " + + protoResponse.getResourcePrototype().getName() + + " could be found!", resourcesResponse.getResource().size() > 0); + + Resource service = resourcesResponse.getResource().get(0); + + AlertDefinition d = generateAlerts(service); + + AlertsResponse response = api.findAlerts(service, 0, System.currentTimeMillis(), + 10, 1, false, false); + hqAssertSuccess(response); + assertTrue(response.getAlert().size() <= 10); + assertTrue(response.getAlert().size() > 0); + + for (Alert a : response.getAlert()) { + validateAlert(a); + } + + List users = createTestUsers(1); + User unprivUser = users.get(0); + AlertApi apiUnpriv = getApi(unprivUser.getName(), TESTUSER_PASSWORD).getAlertApi(); + + // Test marking fixed with an unprivlidged user + Alert a = response.getAlert().get(0); + + StatusResponse fixResponse = apiUnpriv.fixAlert(a.getId()); + hqAssertFailurePermissionDenied(fixResponse); + + // TODO: Valididate fix flag was set? Will require a getById API. + + // Cleanup + StatusResponse deleteResponse = getApi(). + getAlertDefinitionApi().deleteAlertDefinition(d.getId()); + hqAssertSuccess(deleteResponse); + deleteTestUsers(users); + } + public void testFixInvalidAlert() throws Exception { AlertApi api = getAlertApi(); diff --git a/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java b/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java index 2a206767..fda9db76 100644 --- a/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java +++ b/src/org/hyperic/hq/hqapi1/test/AlertTestBase.java @@ -3,12 +3,18 @@ import org.hyperic.hq.hqapi1.AlertApi; import org.hyperic.hq.hqapi1.AlertDefinitionBuilder; import org.hyperic.hq.hqapi1.AlertDefinitionApi; +import org.hyperic.hq.hqapi1.MetricDataApi; +import org.hyperic.hq.hqapi1.HQApi; +import org.hyperic.hq.hqapi1.MetricApi; import org.hyperic.hq.hqapi1.types.AlertDefinition; import org.hyperic.hq.hqapi1.types.Resource; import org.hyperic.hq.hqapi1.types.StatusResponse; import org.hyperic.hq.hqapi1.types.AlertDefinitionsResponse; import org.hyperic.hq.hqapi1.types.AlertsResponse; import org.hyperic.hq.hqapi1.types.Alert; +import org.hyperic.hq.hqapi1.types.MetricsResponse; +import org.hyperic.hq.hqapi1.types.Metric; +import org.hyperic.hq.hqapi1.types.DataPoint; import java.util.Random; import java.util.List; @@ -40,32 +46,57 @@ protected void validateAlert(Alert a) throws Exception { * * @return The AlertDefinition that was created to generate the alerts. */ - protected AlertDefinition generateAlerts() throws Exception { - Resource platform = getLocalPlatformResource(false, false); - AlertDefinition d = new AlertDefinition(); + protected AlertDefinition generateAlerts(Resource resource) throws Exception { + HQApi api = getApi(); + AlertDefinitionApi defApi = api.getAlertDefinitionApi(); + MetricApi metricApi = api.getMetricApi(); + MetricDataApi dataApi = api.getMetricDataApi(); + + // Find availability metric for the passed in resource + MetricsResponse metricsResponse = metricApi.getMetrics(resource, true); + hqAssertSuccess(metricsResponse); + Metric availMetric = null; + for (Metric m : metricsResponse.getMetric()) { + if (m.getName().equals("Availability")) { + availMetric = m; + break; + } + } + assertNotNull("Unable to find Availability metric for " + resource.getName(), + availMetric); + + // Create alert definition + AlertDefinition d = new AlertDefinition(); Random r = new Random(); d.setName("Test Alert Definition" + r.nextInt()); d.setDescription("Definition that will always fire, allowing for testing of Alerts"); d.setPriority(AlertDefinitionBuilder.AlertPriority.MEDIUM.getPriority()); d.setActive(true); - d.setResource(platform); + d.setResource(resource); d.getAlertCondition().add(AlertDefinitionBuilder. - createThresholdCondition(true, "Availability", + createThresholdCondition(true, availMetric.getName(), AlertDefinitionBuilder.AlertComparator.GREATER_THAN, -1)); - AlertDefinitionApi defApi = getApi().getAlertDefinitionApi(); - List definitions = new ArrayList(); definitions.add(d); AlertDefinitionsResponse response = defApi.syncAlertDefinitions(definitions); hqAssertSuccess(response); + // Insert a fake 'up' measurement + List dataPoints = new ArrayList(); + DataPoint dp = new DataPoint(); + dp.setTimestamp(System.currentTimeMillis()); + dp.setValue(1.0); + dataPoints.add(dp); + StatusResponse dataResponse = dataApi.addData(availMetric, dataPoints); + hqAssertSuccess(dataResponse); + // Now we wait.. - System.out.println("Waiting for alerts..."); + System.out.println("Waiting for alerts on " + resource.getName() + "..."); for (int i = 0; i < 120; i++) { // Wait for alerts - AlertsResponse alerts = getAlertApi().findAlerts(platform, 0, + AlertsResponse alerts = getAlertApi().findAlerts(resource, 0, System.currentTimeMillis(), 10, 1, false, false); hqAssertSuccess(alerts);