diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java index a1356ab436..9eddd91aeb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java @@ -120,6 +120,8 @@ public interface DeviceEventManagementService { @PathParam("type")String deviceType, @ApiParam(name = "skipPersist", value = "Is it required to persist the data or not") @QueryParam("skipPersist") boolean skipPersist, + @ApiParam(name = "isSharedWithAllTenants", value = "Should artifacts be available to all tenants") + @QueryParam("isSharedWithAllTenants") boolean isSharedWithAllTenants, @ApiParam(name = "deviceTypeEvent", value = "Add the data to complete the DeviceTypeEvent object.", required = true) @Valid DeviceTypeEvent deviceTypeEvent); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java index a4c871aace..899f84ec70 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java @@ -246,6 +246,10 @@ public interface DeviceTypeManagementAdminService { code = 401, message = "Unauthorized.\n The unauthorized access to the requested resource.", response = ErrorResponse.class), + @ApiResponse( + code = 403, + message = "Forbidden.\n The resource is unavailable for current tenant.", + response = ErrorResponse.class), @ApiResponse( code = 404, message = "Not Found.\n The specified device does not exist", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java index eb2c7558ac..6c04581110 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java @@ -200,6 +200,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe @Override public Response deployDeviceTypeEventDefinition(@PathParam("type") String deviceType, @QueryParam("skipPersist") boolean skipPersist, + @QueryParam("isSharedWithAllTenants") boolean isSharedWithAllTenants, @Valid DeviceTypeEvent deviceTypeEvent) { TransportType transportType = deviceTypeEvent.getTransportType(); EventAttributeList eventAttributes = deviceTypeEvent.getEventAttributeList(); @@ -215,7 +216,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); String streamNameWithVersion = streamName + ":" + Constants.DEFAULT_STREAM_VERSION; publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); - publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, deviceType); + publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, isSharedWithAllTenants, deviceType); if (!skipPersist) { publishEventStore(streamName, Constants.DEFAULT_STREAM_VERSION, eventAttributes); } @@ -226,7 +227,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); - publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, deviceType); + publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, isSharedWithAllTenants, deviceType); } } finally { PrivilegedCarbonContext.endTenantFlow(); @@ -520,7 +521,7 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe private void publishEventReceivers(String streamNameWithVersion, TransportType transportType - , String requestedTenantDomain, String deviceType) + , String requestedTenantDomain, boolean isSharedWithAllTenants, String deviceType) throws RemoteException, UserStoreException, JWTClientException { EventReceiverAdminServiceStub receiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); try { @@ -543,8 +544,13 @@ public class DeviceEventManagementServiceImpl implements DeviceEventManagementSe BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[]; if (transportType == TransportType.MQTT) { basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[3]; - basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("topic", requestedTenantDomain - + "/" + deviceType + "/+/events"); + String topic; + if (isSharedWithAllTenants) { + topic = "+/" + deviceType + "/+/events"; + } else { + topic = requestedTenantDomain + "/" + deviceType + "/+/events"; + } + basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("topic", topic); basicInputAdapterPropertyDtos[1] = getBasicInputAdapterPropertyDto(MQTT_CONTENT_TRANSFORMER_TYPE , MQTT_CONTENT_TRANSFORMER); basicInputAdapterPropertyDtos[2] = getBasicInputAdapterPropertyDto(MQTT_CONTENT_VALIDATOR_TYPE diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java index 7c3703ce13..806952ec37 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java @@ -38,9 +38,12 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; +import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; @@ -110,7 +113,16 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen @POST public Response addDeviceType(DeviceType deviceType) { if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) { + DeviceTypeMetaDefinition deviceTypeMetaDefinition = deviceType.getDeviceTypeMetaDefinition(); try { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if (deviceTypeMetaDefinition.isSharedWithAllTenants() && + !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { + String msg = "Invalid request, device type can only be shared with all the tenants " + + "only if the request is sent by the super tenant"; + log.error(msg); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) != null) { String msg = "Device type already available, " + deviceType.getName(); return Response.status(Response.Status.CONFLICT).entity(msg).build(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java index 3ee922c1f4..168359b487 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java @@ -47,6 +47,9 @@ import org.testng.IObjectFactory; import org.testng.annotations.BeforeClass; import org.testng.annotations.ObjectFactory; import org.testng.annotations.Test; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; import org.wso2.carbon.device.mgt.core.dto.DeviceType; @@ -66,8 +69,9 @@ import static org.mockito.MockitoAnnotations.initMocks; * This class holds the unit tests for the class {@link DeviceTypeManagementAdminService} */ @PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"}) -@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils"}) -@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class}) +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.PrivilegedCarbonContext"}) +@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class, CarbonContext.class}) public class DeviceTypeManagementAdminServiceTest { private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminService.class); @@ -77,6 +81,7 @@ public class DeviceTypeManagementAdminServiceTest { private static final int TEST_DEVICE_TYPE_ID = 12345; private static final int TEST_DEVICE_TYPE_ID_1 = 123452; private static final int TEST_DEVICE_TYPE_ID_2 = 121233452; + private PrivilegedCarbonContext context; private DeviceTypeManagementAdminService deviceTypeManagementAdminService; private DeviceManagementProviderService deviceManagementProviderService; private DeviceTypeGeneratorService deviceTypeGeneratorService; @@ -94,6 +99,8 @@ public class DeviceTypeManagementAdminServiceTest { .mock(DeviceManagementProviderServiceImpl.class, Mockito.RETURNS_MOCKS); this.deviceTypeGeneratorService = Mockito.mock(DeviceTypeGeneratorServiceImpl.class, Mockito.RETURNS_MOCKS); this.deviceTypeManagementAdminService = new DeviceTypeManagementAdminServiceImpl(); + context = Mockito.mock(PrivilegedCarbonContext.class); + Mockito.doReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME).when(context).getTenantDomain(); } @Test(description = "Test get all the device types.") @@ -122,6 +129,8 @@ public class DeviceTypeManagementAdminServiceTest { public void testAddDeviceTypeWithExistingName() throws DeviceManagementException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE_1, TEST_DEVICE_TYPE_ID_1); Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); Assert.assertNotNull(response, "The response should not be null"); @@ -133,6 +142,8 @@ public class DeviceTypeManagementAdminServiceTest { public void testAddDeviceTypeWithUnqualifiedName() throws DeviceManagementException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null); DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE_2, TEST_DEVICE_TYPE_ID_2); Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); @@ -148,6 +159,8 @@ public class DeviceTypeManagementAdminServiceTest { .toReturn(this.deviceManagementProviderService); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService")) .toReturn(this.deviceTypeGeneratorService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null); DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); @@ -171,6 +184,8 @@ public class DeviceTypeManagementAdminServiceTest { public void testAddDeviceTypeWithException() throws DeviceManagementException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenThrow(new DeviceManagementException()); DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/type/mgt/DeviceTypeMetaDefinition.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/type/mgt/DeviceTypeMetaDefinition.java index 98b6c36e32..e609c32266 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/type/mgt/DeviceTypeMetaDefinition.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/type/mgt/DeviceTypeMetaDefinition.java @@ -18,6 +18,7 @@ public class DeviceTypeMetaDefinition { private InitialOperationConfig initialOperationConfig; private License license; private String description; + private boolean isSharedWithAllTenants; public String getDescription() { return description; @@ -83,4 +84,12 @@ public class DeviceTypeMetaDefinition { public void setLicense(License license) { this.license = license; } + + public boolean isSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public void setSharedWithAllTenants(boolean sharedWithAllTenants) { + isSharedWithAllTenants = sharedWithAllTenants; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/HTTPDeviceTypeManagerService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/HTTPDeviceTypeManagerService.java index 8f9f1f4e24..49f8222c02 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/HTTPDeviceTypeManagerService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/HTTPDeviceTypeManagerService.java @@ -112,7 +112,7 @@ public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService imple deviceTypeConfiguration.setPolicyMonitoring(policyMonitoring); ProvisioningConfig provisioningConfig = new ProvisioningConfig(); - provisioningConfig.setSharedWithAllTenants(false); + provisioningConfig.setSharedWithAllTenants(deviceTypeMetaDefinition.isSharedWithAllTenants()); deviceTypeConfiguration.setProvisioningConfig(provisioningConfig); PushNotificationConfig pushNotificationConfig = deviceTypeMetaDefinition.getPushNotificationConfig();