diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseServiceImpl.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseServiceImpl.java
index f99f2ed5c7..72ccc6fe8f 100644
--- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseServiceImpl.java
+++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseServiceImpl.java
@@ -48,7 +48,7 @@ import java.util.Properties;
public class AndroidSenseServiceImpl implements AndroidSenseService {
private static Log log = LogFactory.getLog(AndroidSenseServiceImpl.class);
- private static String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1883";
+ private static String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1886";
@Path("device/{deviceId}/words")
@POST
diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/constants/AndroidSenseConstants.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/constants/AndroidSenseConstants.java
index ea62644b93..e1419844c7 100644
--- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/constants/AndroidSenseConstants.java
+++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/constants/AndroidSenseConstants.java
@@ -40,6 +40,6 @@ public class AndroidSenseConstants {
public static final String HOST_NAME = "HostName";
public static final String LOCALHOST = "localhost";
public static final String CONFIG_TYPE = "general";
- public static final String DEFAULT_ENDPOINT = "tcp://localhost:1883";
+ public static final String DEFAULT_ENDPOINT = "tcp://localhost:1886";
}
diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java
index d12a2df048..d8c955a158 100644
--- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java
+++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java
@@ -64,7 +64,7 @@ public class ZipUtil {
private static final String HTTPS_PROTOCOL_APPENDER = "https://";
private static final String HTTP_PROTOCOL_APPENDER = "http://";
private static final String CONFIG_TYPE = "general";
- private static final String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1883";
+ private static final String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1886";
public ZipArchive createZipFile(String owner, String tenantDomain, String deviceType,
String deviceId, String deviceName, String token,
diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java
index feb8135db1..2c6cd28407 100644
--- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java
+++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/ZipUtil.java
@@ -67,7 +67,7 @@ public class ZipUtil {
private static final String HTTPS_PROTOCOL_APPENDER = "https://";
private static final String HTTP_PROTOCOL_APPENDER = "http://";
private static final String CONFIG_TYPE = "general";
- private static final String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1883";
+ private static final String DEFAULT_MQTT_ENDPOINT = "tcp://localhost:1886";
public static final String HOST_NAME = "HostName";
public ZipArchive createZipFile(String owner, String deviceType, String deviceId, String deviceName,
diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java
index b505832e5b..0d163c9fd2 100644
--- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java
+++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java
@@ -46,7 +46,7 @@ public class VirtualFireAlarmConstants {
public static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
public static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip";
public static final int CARBON_DEFAULT_PORT_OFFSET = 0;
- public static final int DEFAULT_MQTT_PORT = 1883;
+ public static final int DEFAULT_MQTT_PORT = 1886;
//xmpp transport related constants
public static final String XMPP_ADAPTER_NAME = "virtual_firealarm_xmpp";
diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java
index 6433bf42bd..5cede58f6f 100644
--- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java
+++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/java/org/wso2/carbon/device/mgt/input/adapter/mqtt/util/PropertyUtils.java
@@ -27,7 +27,7 @@ public class PropertyUtils {
private static final String CARBON_CONFIG_PORT_OFFSET = "Ports.Offset";
private static final String DEFAULT_CARBON_LOCAL_IP_PROPERTY = "carbon.local.ip";
private static final int CARBON_DEFAULT_PORT_OFFSET = 0;
- private static final int DEFAULT_MQTT_PORT = 1883;
+ private static final int DEFAULT_MQTT_PORT = 1886;
//This method is only used if the mb features are within DAS.
public static String replaceMqttProperty (String urlWithPlaceholders) {
diff --git a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties
index acc6cfd33a..f75e4075c8 100644
--- a/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties
+++ b/components/extensions/cdmf-transport-adapters/input/org.wso2.carbon.device.mgt.input.adapter.mqtt/src/main/resources/org/wso2/carbon/device/mgt/input/adapter/mqtt/i18n/Resources.properties
@@ -29,7 +29,7 @@ dcrUrl=dcrUrl
dcrUrl.hint=dynamic client registration endpoint URL to create application (if required) eg: https://localhost:9443/dynamic-client-web/register
contentValidator=contentValidation
contentValidator.hint=Class Name of the content Validation or 'default' to set default class, required to implement (if required)
-url.hint=MQTT broker url tcp://localhost:1883
+url.hint=MQTT broker url tcp://localhost:1886
cleanSession=Clean Session
cleanSession.hint=Persist topic subscriptions and ack positions across client sessions
keepAlive=Keep Alive (In seconds)
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml
new file mode 100644
index 0000000000..3ba0ed3cf5
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/pom.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ mb-extensions
+ 2.2.6-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+ bundle
+ WSO2 Carbon - Component - MQTT - Authorization Manager
+ MQTT authorization manager based on Carbon device manager
+ http://wso2.org
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.andes.wso2
+ andes
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.api
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.core
+
+
+ commons-lang
+ commons-lang
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal
+
+
+ !org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal,
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.*
+
+
+ org.apache.log4j,
+ org.dna.mqtt.moquette.server,
+ org.wso2.andes.configuration.enums,
+ org.wso2.andes.mqtt,
+ org.wso2.carbon.context,
+ org.jaxen,
+ org.apache.axiom.*,
+ org.wso2.securevault,
+ org.apache.commons.*,
+ org.osgi.service.component,
+ org.wso2.carbon.user.core.service,
+ org.wso2.carbon.user.core.tenant,
+ org.wso2.carbon.user.api,
+ *;resolution:=optional
+
+ *
+
+
+
+
+
+
+
+
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java
new file mode 100644
index 0000000000..effd878ab0
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/DeviceAccessBasedMQTTAuthorizer.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dna.mqtt.moquette.server.IAuthorizer;
+import org.wso2.andes.configuration.enums.MQTTAuthoriztionPermissionLevel;
+import org.wso2.andes.mqtt.MQTTAuthorizationSubject;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal.AuthorizationDataHolder;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.user.api.UserRealm;
+import org.wso2.carbon.user.api.UserStoreException;
+
+import java.util.List;
+
+/**
+ * Authorize the connecting users against Carbon Permission Model. Intended usage is
+ * via providing fully qualified class name in broker.xml
+ *
+ * This is just a simple authorization model. For dynamic topics use an implementation based on IAuthorizer
+ */
+public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
+
+ private static final String SCOPE_IDENTIFIER = "scope";
+ private static final String UI_EXECUTE = "ui.execute";
+ private static Log logger = LogFactory.getLog(DeviceAccessBasedMQTTAuthorizer.class);
+ AuthorizationConfigurationManager MQTTAuthorizationConfiguration;
+
+ public DeviceAccessBasedMQTTAuthorizer() {
+ this.MQTTAuthorizationConfiguration = AuthorizationConfigurationManager.getInstance();
+ }
+
+ /**
+ * {@inheritDoc} Authorize the user against carbon device mgt model.
+ */
+ @Override
+ public boolean isAuthorizedForTopic(MQTTAuthorizationSubject authorizationSubject, String topic,
+ MQTTAuthoriztionPermissionLevel permissionLevel) {
+ if (isUserAuthorized(authorizationSubject, MQTTAuthorizationConfiguration.getAdminPermission(), UI_EXECUTE)) {
+ return true;
+ }
+ String topics[] = topic.split("/");
+ if (topics.length < 3) {
+ return false;
+ }
+ String tenantIdFromTopic = topics[0];
+ if (!tenantIdFromTopic.equals(authorizationSubject.getTenantDomain())) {
+ return false;
+ }
+ String deviceType = topics[1];
+ String deviceId = topics[2];
+ Object scopeObject = authorizationSubject.getProperties().get(SCOPE_IDENTIFIER);
+
+ if (!deviceId.isEmpty() && !deviceType.isEmpty() && scopeObject != null) {
+ List scopes = (List) scopeObject;
+ String permissionScope = MQTTAuthorizationConfiguration.getMQTTPublisherScopeIdentifier();
+ if (permissionLevel == MQTTAuthoriztionPermissionLevel.SUBSCRIBE) {
+ permissionScope = MQTTAuthorizationConfiguration.getMQTTSubscriberScopeIdentifier();
+ }
+ String requiredScope = MQTTAuthorizationConfiguration.getDevicemgtScopeIdentifier() + ":" + deviceType + ":"
+ + deviceId + ":" + permissionScope;
+ for (String scope : scopes) {
+ if (requiredScope.equals(scope)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc} Authorized the user against carbon device mgt model.
+ */
+ @Override
+ public boolean isAuthorizedToConnect(MQTTAuthorizationSubject authorizationSubject) {
+ return isUserAuthorized(authorizationSubject, MQTTAuthorizationConfiguration.getConnectionPermission()
+ , UI_EXECUTE);
+ }
+
+ /**
+ * Check whether the client is authorized with the given permission and action.
+ *
+ * @param authorizationSubject this contains the client information
+ * @param permission Carbon permission that requires for the use
+ * @param action Carbon permission action that requires for the given permission.
+ * @return boolean - true if user is authorized else return false.
+ */
+ private boolean isUserAuthorized(MQTTAuthorizationSubject authorizationSubject, String permission, String action) {
+ String username = authorizationSubject.getUsername();
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
+ authorizationSubject.getTenantDomain(), true);
+ int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
+ UserRealm userRealm = AuthorizationDataHolder.getInstance().getRealmService()
+ .getTenantUserRealm(tenantId);
+ return userRealm != null && userRealm.getAuthorizationManager() != null &&
+ userRealm.getAuthorizationManager().isUserAuthorized(username, permission, action);
+ } catch (UserStoreException e) {
+ String errorMsg = String.format("Unable to authorize the user : %s", username);
+ logger.error(errorMsg, e);
+ return false;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ }
+}
\ No newline at end of file
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfiguration.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfiguration.java
new file mode 100644
index 0000000000..1a417a9245
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfiguration.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.xpath.AXIOMXPath;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jaxen.JaxenException;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.exception.AuthorizationException;
+import org.wso2.carbon.utils.ServerConstants;
+import org.wso2.securevault.SecretResolver;
+import org.wso2.securevault.SecretResolverFactory;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This class acts as a access point to retrieve config parameters used within the authorization.
+ * this configuration is read from broker.xml
+ */
+public class AuthorizationConfiguration {
+ /**
+ * Reserved Prefixes that activate different processing logic.
+ */
+ private static final String LIST_TYPE = "LIST_";
+ private static final QName SECURE_VAULT_QNAME = new QName("http://org.wso2.securevault/configuration"
+ , "secretAlias");
+ /**
+ * Common Error states
+ */
+ private static final String GENERIC_CONFIGURATION_PARSE_ERROR = "Error occurred when trying to parse " +
+ "configuration value {0}.";
+ private static final String NO_CHILD_FOR_KEY_IN_PROPERTY = "There was no child at the given key {0} for the " +
+ "parent property {1}.";
+ private static final String PROPERTY_NOT_A_LIST = "The input property {0} does not contain a list of child " +
+ "properties.";
+ /**
+ * location to broker.xml
+ */
+ private static final String ROOT_CONFIG_FILE_PATH = System.getProperty(ServerConstants.CARBON_HOME)
+ + "/repository/conf/";
+ /**
+ * File name of the main configuration file.
+ */
+ private static final String ROOT_CONFIG_FILE_NAME = "broker.xml";
+ private static Log log = LogFactory.getLog(AuthorizationConfigurationManager.class);
+ private static CompositeConfiguration compositeConfiguration;
+ /**
+ * This hashmap is used to maintain any properties that were read from broker.xml
+ */
+ private static ConcurrentHashMap propertyList;
+
+ public static void initialize() throws AuthorizationException {
+ String brokerConfigFilePath = ROOT_CONFIG_FILE_PATH + ROOT_CONFIG_FILE_NAME;
+ if (log.isDebugEnabled()) {
+ log.debug("Configuration located at : " + brokerConfigFilePath);
+ }
+ try {
+ compositeConfiguration = new CompositeConfiguration();
+ compositeConfiguration.setDelimiterParsingDisabled(true);
+ XMLConfiguration rootConfiguration = new XMLConfiguration();
+ rootConfiguration.setDelimiterParsingDisabled(true);
+ rootConfiguration.setFileName(brokerConfigFilePath);
+ rootConfiguration.setExpressionEngine(new XPathExpressionEngine());
+ rootConfiguration.load();
+ readConfigurationFromFile(brokerConfigFilePath);
+ compositeConfiguration.addConfiguration(rootConfiguration);
+ } catch (FileNotFoundException e) {
+ String error = "Error occurred when trying to read the configuration file : " + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ } catch (JaxenException e) {
+ String error = "Error occurred when trying to process file : " + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ } catch (XMLStreamException e) {
+ String error = "Error occurred when trying to process file : " + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ } catch (ConfigurationException e) {
+ String error = "Error occurred when trying to process file :" + brokerConfigFilePath;
+ log.error(error, e);
+ throw new AuthorizationException(error, e);
+ }
+ }
+
+
+ private static void readConfigurationFromFile(String filePath) throws FileNotFoundException, JaxenException
+ , XMLStreamException {
+ propertyList = new ConcurrentHashMap();
+ StAXOMBuilder stAXOMBuilder = new StAXOMBuilder(new FileInputStream(new File(filePath)));
+ OMElement dom = stAXOMBuilder.getDocumentElement();
+ SecretResolver secretResolver = SecretResolverFactory.create(dom, false);
+ AXIOMXPath xpathExpression = new AXIOMXPath("//*[@*[local-name() = \'secretAlias\']]");
+ List nodeList = xpathExpression.selectNodes(dom);
+ String propertyKey;
+ String propertyValue;
+ for (Iterator i$ = nodeList.iterator(); i$.hasNext(); propertyList.put(propertyKey, propertyValue)) {
+ Object o = i$.next();
+ propertyKey = ((OMElement) o).getAttributeValue(SECURE_VAULT_QNAME);
+ propertyValue = "";
+ if (secretResolver != null && secretResolver.isInitialized()) {
+ if (secretResolver.isTokenProtected(propertyKey)) {
+ propertyValue = secretResolver.resolve(propertyKey);
+ }
+ } else {
+ log.warn("Error while reading properties form file");
+ }
+ }
+
+ }
+
+ /**
+ * Using this method, you can access a singular property of a child.
+ * example,
+ *
+ * /permission/admin/device-mgt/user
+ * /permission/admin/device-mgt/admin
+ * mqtt-subscriber
+ * mqtt-subscriber
+ * device-mgt
+ * scenario.
+ *
+ * @param configurationProperty relevant enum value (e.g.- above scenario -> org.wso2.carbon.andes.extensions
+ * .device.mgt.mqtt.authorization.config.TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES)
+ * @param key key of the child of whom you seek the value (e.g. above scenario -> "property list")
+ */
+ static T readValueOfChildByKey(MQTTConfiguration configurationProperty, String key) {
+
+ String constructedKey = configurationProperty.get().getKeyInFile().replace("{key}",
+ key);
+ try {
+ return (T) deriveValidConfigurationValue(constructedKey,
+ configurationProperty.get().getDataType(),
+ configurationProperty.get().getDefaultValue());
+ } catch (ConfigurationException e) {
+ log.error(MessageFormat.format(NO_CHILD_FOR_KEY_IN_PROPERTY, key, configurationProperty), e);
+ return null;
+ }
+ }
+
+
+ /**
+ * Use this method when you need to acquire a list of properties of same group.
+ *
+ * @param configurationProperty relevant enum value (e.g.- org.wso2.carbon.andes.extensions
+ * .device.mgt.mqtt.authorization.config.LIST_TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES)
+ * @return String list of required property values
+ */
+ static List readValueList(MQTTConfiguration configurationProperty) {
+
+ if (configurationProperty.toString().startsWith(LIST_TYPE)) {
+ return Arrays.asList(compositeConfiguration.getStringArray(configurationProperty.get().getKeyInFile()));
+ } else {
+ log.error(MessageFormat.format(PROPERTY_NOT_A_LIST, configurationProperty));
+ return new ArrayList<>();
+ }
+ }
+
+
+ /**
+ * Given the data type and the value read from a config, this returns the parsed value
+ * of the property.
+ *
+ * @param key The Key to the property being read (n xpath format as contained in file.)
+ * @param dataType Expected data type of the property
+ * @param defaultValue This parameter should NEVER be null since we assign a default value to
+ * every config property.
+ * @param Expected data type of the property
+ * @return Value of config in the expected data type.
+ * @throws ConfigurationException if there are any configuration issues
+ */
+ private static T deriveValidConfigurationValue(String key, Class dataType,
+ String defaultValue) throws ConfigurationException {
+ if (log.isDebugEnabled()) {
+ log.debug("Reading configuration value " + key);
+ }
+ String readValue = compositeConfiguration.getString(key);
+ String validValue = defaultValue;
+ if (StringUtils.isBlank(readValue)) {
+ log.warn("Error when trying to read property : " + key + ". Switching to " + "default value : " +
+ defaultValue);
+ } else {
+ validValue = overrideWithDecryptedValue(key, readValue);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Valid value read for andes configuration property " + key + " is : " + validValue);
+ }
+ try {
+ return dataType.getConstructor(String.class).newInstance(validValue);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
+ throw new ConfigurationException(MessageFormat.format(GENERIC_CONFIGURATION_PARSE_ERROR, key), e);
+ }
+ }
+
+ /**
+ * If the property is contained in the propertyList, replace the raw value with that value.
+ *
+ * @param keyInFile xpath expression used to extract the value from file.
+ * @param rawValue The value read from the file without any processing.
+ * @return the value with corresponding to actual value.
+ */
+ private static String overrideWithDecryptedValue(String keyInFile, String rawValue) {
+ if (!StringUtils.isBlank(keyInFile)) {
+ String key = keyInFile.replaceAll("/", ".");
+ if (propertyList.containsKey(key)) {
+ return propertyList.get(key);
+ }
+ }
+ return rawValue;
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfigurationManager.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfigurationManager.java
new file mode 100644
index 0000000000..c477af77a6
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/AuthorizationConfigurationManager.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.List;
+
+public class AuthorizationConfigurationManager {
+
+ private static final String CONNECTION_PERMISSION = "connectionPermission";
+ private static final String ADMIN_PERMISSION = "adminPermission";
+ private static final String MQTT_PUBLISHER_SCOPE_IDENTIFIER = "MQTTPublisherScopeIdentifier";
+ private static final String MQTT_SUBSCRIBER_SCOPE_IDENTIFIER = "MQTTSubscriberScopeIdentifier";
+ private static final String DEVICE_MGT_SCOPE_IDENTIFIER = "devicemgtScopeIdentifier";
+ private static final AuthorizationConfigurationManager oAuthConfigurationManager
+ = new AuthorizationConfigurationManager();
+ private static Log logger = LogFactory.getLog(AuthorizationConfigurationManager.class);
+ private String connectionPermission;
+ private String adminPermission;
+ private String MQTTPublisherScopeIdentifier;
+ private String MQTTSubscriberScopeIdentifier;
+ private String devicemgtScopeIdentifier;
+
+ private AuthorizationConfigurationManager() {
+
+ }
+
+ public static AuthorizationConfigurationManager getInstance() {
+ return oAuthConfigurationManager;
+ }
+
+ public String getConnectionPermission() {
+ return connectionPermission;
+ }
+
+ public void setConnectionPermission(String connectionPermission) {
+ if (connectionPermission != null) {
+ this.connectionPermission = connectionPermission;
+ } else {
+ logger.error("Connection permission can't be null ");
+ }
+ }
+
+ public String getAdminPermission() {
+ return adminPermission;
+ }
+
+ public void setAdminPermission(String adminPermission) {
+ if (adminPermission != null) {
+ this.adminPermission = adminPermission;
+ } else {
+ logger.error("admin permission can't be null ");
+ }
+ }
+
+ public String getMQTTPublisherScopeIdentifier() {
+ return MQTTPublisherScopeIdentifier;
+ }
+
+ public void setMQTTPublisherScopeIdentifier(String MQTTPublisherScopeIdentifier) {
+ if (MQTTPublisherScopeIdentifier != null) {
+ this.MQTTPublisherScopeIdentifier = MQTTPublisherScopeIdentifier;
+ } else {
+ logger.error("MQTT publisher scope identifier can't be null ");
+ }
+ }
+
+ public String getMQTTSubscriberScopeIdentifier() {
+ return MQTTSubscriberScopeIdentifier;
+ }
+
+ public void setMQTTSubscriberScopeIdentifier(String MQTTSubscriberScopeIdentifier) {
+ if (MQTTSubscriberScopeIdentifier != null) {
+ this.MQTTSubscriberScopeIdentifier = MQTTSubscriberScopeIdentifier;
+ } else {
+ logger.error("MQTT subscriber scope identifier can't be null ");
+ }
+ }
+
+ public String getDevicemgtScopeIdentifier() {
+ return devicemgtScopeIdentifier;
+ }
+
+ public void setDevicemgtScopeIdentifier(String devicemgtScopeIdentifier) {
+ if (devicemgtScopeIdentifier != null) {
+ this.devicemgtScopeIdentifier = devicemgtScopeIdentifier;
+ } else {
+ logger.error("Device management scope identifier can't be null ");
+ }
+ }
+
+ /**
+ * Initialize the configuration properties that required for MQTT Authorization
+ */
+ public synchronized void initConfig() {
+ List mqttTransportAuthorizationProperties = AuthorizationConfiguration.readValueList(MQTTConfiguration
+ .LIST_TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES);
+ for (String property : mqttTransportAuthorizationProperties) {
+ String propertyValue = AuthorizationConfiguration.readValueOfChildByKey(
+ MQTTConfiguration.TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES, property);
+ switch (property) {
+ case CONNECTION_PERMISSION:
+ setConnectionPermission(propertyValue);
+ break;
+ case ADMIN_PERMISSION:
+ setAdminPermission(propertyValue);
+ break;
+ case MQTT_PUBLISHER_SCOPE_IDENTIFIER:
+ setMQTTPublisherScopeIdentifier(propertyValue);
+ break;
+ case MQTT_SUBSCRIBER_SCOPE_IDENTIFIER:
+ setMQTTSubscriberScopeIdentifier(propertyValue);
+ break;
+ case DEVICE_MGT_SCOPE_IDENTIFIER:
+ setDevicemgtScopeIdentifier(propertyValue);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/MQTTConfiguration.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/MQTTConfiguration.java
new file mode 100644
index 0000000000..9e56118da6
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/config/MQTTConfiguration.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config;
+
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util.ImmutableMetaProperties;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util.MetaProperties;
+
+import java.util.List;
+
+public enum MQTTConfiguration {
+
+ /**
+ * List of properties that can define how the server will authenticate the user with the authentication service.
+ */
+ LIST_TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES("transports/mqtt/security/authorizer/property/@name", "", List.class),
+
+ /**
+ * This can be used to access a property by giving its key. e.g. hosturl
+ */
+ TRANSPORT_MQTT_AUTHORIZATION_PROPERTIES("transports/mqtt/security/authorizer/property[@name = '{key}']", ""
+ , String.class);
+
+ /**
+ * Meta data about configuration.
+ */
+ private final MetaProperties metaProperties;
+
+ /**
+ * Constructor to define a configuration in broker.
+ *
+ * @param keyInFile Xpath (or any key value) which can be used to identify the configuration in the file.
+ * @param defaultValue the default value
+ * @param dataType data type of the config ( e.g. boolean, string )
+ */
+ MQTTConfiguration(String keyInFile, String defaultValue, Class> dataType) {
+ // We need to pass the enum name as the identifier : therefore this.name()
+ this.metaProperties = new ImmutableMetaProperties(this.name(), keyInFile, defaultValue, dataType);
+ }
+
+ public MetaProperties get() {
+ return metaProperties;
+ }
+
+
+}
+
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/exception/AuthorizationException.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/exception/AuthorizationException.java
new file mode 100644
index 0000000000..4343886350
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/exception/AuthorizationException.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.exception;
+
+public class AuthorizationException extends Exception {
+ /**
+ * Default Serialization UID
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * error code for our custom exception type to identify specific scenarios and handle them properly.
+ */
+ private String errorCode = "";
+
+ public AuthorizationException() {
+ }
+
+ public AuthorizationException(String message) {
+ super(message);
+ }
+
+ /***
+ * Constructor
+ * @param message descriptive message
+ * @param errorCode one of the above defined constants that classifies the error.
+ */
+ public AuthorizationException(String message, String errorCode) {
+ super(message);
+ this.errorCode = errorCode;
+ }
+
+ /***
+ * Constructor
+ * @param message descriptive message
+ * @param cause reference to the exception for reference.
+ */
+ public AuthorizationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /***
+ * Constructor
+ * @param message descriptive message
+ * @param errorCode one of the above defined constants that classifies the error.
+ * @param cause reference to the exception for reference.
+ */
+ public AuthorizationException(String message, String errorCode, Throwable cause) {
+ super(message, cause);
+ this.errorCode = errorCode;
+ }
+
+ /***
+ * Constructor
+ * @param cause reference to the exception for reference.
+ */
+ public AuthorizationException(Throwable cause) {
+ super(cause);
+ }
+
+ /***
+ * One of the above defined constants that classifies the error. e.g.- MESSAGE_CONTENT_OBSOLETE
+ * @return
+ */
+ public String getErrorCode() {
+ return errorCode;
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationDataHolder.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationDataHolder.java
new file mode 100644
index 0000000000..f36ac6d458
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationDataHolder.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal;
+
+import org.wso2.carbon.user.core.service.RealmService;
+import org.wso2.carbon.user.core.tenant.TenantManager;
+
+public class AuthorizationDataHolder {
+
+ private static AuthorizationDataHolder thisInstance = new AuthorizationDataHolder();
+ private RealmService realmService;
+ private TenantManager tenantManager;
+
+ private AuthorizationDataHolder() {
+ }
+
+ public static AuthorizationDataHolder getInstance() {
+ return thisInstance;
+ }
+
+ public RealmService getRealmService() {
+ return realmService;
+ }
+
+ public void setRealmService(RealmService realmService) {
+ this.realmService = realmService;
+ this.setTenantManager(realmService);
+ }
+
+ public TenantManager getTenantManager() {
+ return tenantManager;
+ }
+
+ private void setTenantManager(RealmService realmService) {
+ if (realmService == null) {
+ throw new IllegalStateException("Realm service is not initialized properly");
+ }
+ this.tenantManager = realmService.getTenantManager();
+ }
+
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationServiceComponent.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationServiceComponent.java
new file mode 100644
index 0000000000..7a72d5969a
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/internal/AuthorizationServiceComponent.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.service.component.ComponentContext;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfiguration;
+import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * @scr.component name="org.wso2.carbon.devicemgt.policy.manager" immediate="true"
+ * @scr.reference name="user.realmservice.default"
+ * interface="org.wso2.carbon.user.core.service.RealmService"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setRealmService"
+ * unbind="unsetRealmService"
+ */
+@SuppressWarnings("unused")
+public class AuthorizationServiceComponent {
+
+ private static Log log = LogFactory.getLog(AuthorizationServiceComponent.class);
+
+ protected void activate(ComponentContext componentContext) {
+ try {
+ AuthorizationConfiguration.initialize();
+ AuthorizationConfigurationManager.getInstance().initConfig();
+ } catch (Throwable e) {
+ log.error("Failed to activate org.wso2.carbon.andes.authorization.internal." +
+ "AuthorizationServiceComponent : " + e);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ protected void deactivate(ComponentContext componentContext) {
+
+ }
+
+ /**
+ * Sets Realm Service
+ *
+ * @param realmService An instance of RealmService
+ */
+ protected void setRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting Realm Service");
+ }
+ AuthorizationDataHolder.getInstance().setRealmService(realmService);
+ }
+
+ /**
+ * Unsets Realm Service
+ *
+ * @param realmService An instance of RealmService
+ */
+ protected void unsetRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unsetting Realm Service");
+ }
+ AuthorizationDataHolder.getInstance().setRealmService(null);
+ }
+
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/ImmutableMetaProperties.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/ImmutableMetaProperties.java
new file mode 100644
index 0000000000..5ff2b92dab
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/ImmutableMetaProperties.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util;
+
+/**
+ * This class contains the immutable meta attributes of a config property. These are
+ * immutable so that enums can contain them.
+ */
+public final class ImmutableMetaProperties implements MetaProperties {
+
+ private final String keyInFile;
+ private final String defaultValue;
+ private final Class> dataType;
+ private final String name;
+
+ /**
+ * constructor
+ *
+ * @param keyInFile xpath expression to the property in the config file
+ * @param defaultValue default value of property in case its not specified or found in config files.
+ * @param dataType expected data type of the property
+ */
+ public ImmutableMetaProperties(String name, String keyInFile, String defaultValue, Class> dataType) {
+ this.name = name;
+ this.keyInFile = keyInFile;
+ this.defaultValue = defaultValue;
+ this.dataType = dataType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getKeyInFile() {
+ return keyInFile;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class> getDataType() {
+ return dataType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "Property : " + keyInFile + " data-type : " + dataType.getName() + " default value" +
+ " : " + defaultValue;
+ }
+}
diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/MetaProperties.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/MetaProperties.java
new file mode 100644
index 0000000000..003dcd12f2
--- /dev/null
+++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/mqtt/authorization/util/MetaProperties.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.util;
+
+/**
+ * Contains methods that should be implemented to access meta properties of a config
+ * property.
+ */
+public interface MetaProperties {
+
+ /**
+ * @return actual key with which the property is set in relevant config file.
+ */
+ String getKeyInFile();
+
+ /**
+ * @return Default value specified for the config property,
+ * in case it is not set in file.
+ */
+ String getDefaultValue();
+
+ /**
+ * @return Datatype of the property. (There could be numeric,date or boolean values.)
+ */
+ Class> getDataType();
+
+ /**
+ * @return Name of the property (e.g. TRANSPORTS_AMQP_DEFAULT_CONNECTION_PORT)
+ */
+ String getName();
+
+}
diff --git a/components/extensions/mb-extensions/pom.xml b/components/extensions/mb-extensions/pom.xml
new file mode 100644
index 0000000000..eb13c05718
--- /dev/null
+++ b/components/extensions/mb-extensions/pom.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ extensions
+ 2.2.6-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ mb-extensions
+ pom
+ WSO2 Carbon - MB Extension
+ http://wso2.org
+
+
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+ 1.7.2
+
+
+ generate-scr-scrdescriptor
+
+ scr
+
+
+
+
+
+
+
+
diff --git a/components/extensions/pom.xml b/components/extensions/pom.xml
index b8d2076d76..1e3c2c3d4b 100644
--- a/components/extensions/pom.xml
+++ b/components/extensions/pom.xml
@@ -35,6 +35,7 @@
appm-connector
cdmf-transport-adapters
+ mb-extensions
diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs
index c46c188d12..07a938bdbd 100644
--- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs
+++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs
@@ -114,7 +114,7 @@
Operations
- {{unit "cdmf.unit.device.type.android.operation-bar" deviceType=deviceView.deviceType ownership=deviceView.ownership}}
+ {{unit "cdmf.unit.device.operation-bar" device=device backendApiUri=backendApiUri autoCompleteParams=autoCompleteParams}}
{{/if}}
diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.json b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.json
index 787e8b1dcd..688e939808 100644
--- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.json
+++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.json
@@ -1,4 +1,3 @@
{
- "version": "1.0.0",
- "extends": "cdmf.unit.device.view"
+ "version": "1.0.0"
}
\ No newline at end of file
diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.json b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.json
index 56a988c763..688e939808 100644
--- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.json
+++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/operation-bar.json
@@ -1,4 +1,3 @@
{
- "version": "1.0.0",
- "extends": "cdmf.unit.device.operation-bar"
+ "version": "1.0.0"
}
\ No newline at end of file
diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js
new file mode 100755
index 0000000000..8011137ee1
--- /dev/null
+++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/js/type-view.js
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var modalPopup = ".modal",
+ modalPopupContainer = modalPopup + " .modal-content",
+ modalPopupContent = modalPopup + " .modal-content";
+
+var emmAdminBasePath = "/api/device-mgt/v1.0";
+
+//function openCollapsedNav() {
+// $(".wr-hidden-nav-toggle-btn").addClass("active");
+// $("#hiddenNav").slideToggle("slideDown", function () {
+// if ($(this).css("display") == "none") {
+// $(".wr-hidden-nav-toggle-btn").removeClass("active");
+// }
+// });
+//}
+
+/*
+ * set popup maximum height function.
+ */
+function setPopupMaxHeight() {
+ var maxHeight = "max-height";
+ var marginTop = "margin-top";
+ var body = "body";
+ $(modalPopupContent).css(maxHeight, ($(body).height() - ($(body).height() / 100 * 30)));
+ $(modalPopupContainer).css(marginTop, (-($(modalPopupContainer).height() / 2)));
+}
+
+/*
+ * show popup function.
+ */
+function showPopup() {
+ $(modalPopup).modal('show');
+}
+
+/*
+ * hide popup function.
+ */
+function hidePopup() {
+ $(modalPopupContent).html("");
+ $(modalPopupContent).removeClass("operation-data");
+ $(modalPopup).modal('hide');
+ $('body').removeClass('modal-open').css('padding-right','0px');
+ $('.modal-backdrop').remove();
+}
+
+/*
+ * QR-code generation function.
+ */
+function generateQRCode(qrCodeClass) {
+ var enrollmentURL = $("#qr-code-modal").data("enrollment-url");
+ $(qrCodeClass).qrcode({
+ text: enrollmentURL,
+ width: 200,
+ height: 200
+ });
+}
+
+function toggleEnrollment() {
+ console.log("something happenedfd!");
+ $(".modal-content").html($("#qr-code-modal").html());
+ generateQRCode(".modal-content .qr-code");
+ showPopup();
+}
+
+var updateNotificationCountOnSuccess = function (data, textStatus, jqXHR) {
+ var notificationBubble = "#notification-bubble";
+ if (jqXHR.status == 200 && data) {
+ var responsePayload = JSON.parse(data);
+ var newNotificationsCount = responsePayload["count"];
+ if (newNotificationsCount > 0) {
+ $(notificationBubble).html(newNotificationsCount);
+ $(notificationBubble).show();
+ } else {
+ $(notificationBubble).hide();
+ }
+ }
+};
+
+function updateNotificationCountOnError() {
+ var notificationBubble = "#notification-bubble";
+ $(notificationBubble).html("Error");
+ $(notificationBubble).show();
+}
+
+function loadNewNotificationsOnSideViewPanel() {
+ if ($("#right-sidebar").attr("is-authorized") == "false") {
+ $("#notification-bubble-wrapper").remove();
+ } else {
+ var serviceURL = emmAdminBasePath + "/notifications?status=NEW";
+ invokerUtil.get(serviceURL, updateNotificationCountOnSuccess, updateNotificationCountOnError);
+ loadNewNotifications();
+ }
+}
+
+function loadNewNotifications() {
+ var messageSideBar = ".sidebar-messages";
+ if ($("#right-sidebar").attr("is-authorized") == "false") {
+ $(messageSideBar).html("You are not authorized to view notifications.
");
+ } else {
+ var notifications = $("#notifications");
+ var currentUser = notifications.data("currentUser");
+
+ $.template("notification-listing", notifications.attr("src"), function (template) {
+ var serviceURL = emmAdminBasePath + "/notifications?offset=0&limit=5&status=NEW";
+ invokerUtil.get(
+ serviceURL,
+ // on success
+ function (data, textStatus, jqXHR) {
+ if (jqXHR.status == 200 && data) {
+ var viewModel = {};
+ var responsePayload = JSON.parse(data);
+ if (responsePayload["notifications"]) {
+ if (responsePayload.count > 0) {
+ viewModel["notifications"] = responsePayload["notifications"];
+ viewModel["appContext"] = context;
+ $(messageSideBar).html(template(viewModel));
+ } else {
+ $(messageSideBar).html('No new notifications found...
');
+ }
+ } else {
+ $(messageSideBar).html("Unexpected error " +
+ "occurred while loading new notifications.
");
+ }
+ }
+ },
+ // on error
+ function (jqXHR) {
+ if (jqXHR.status = 500) {
+ $(messageSideBar).html("Unexpected error occurred while trying " +
+ "to retrieve any new notifications.
");
+ }
+ }
+ );
+ });
+ }
+}
+
+/**
+ * Toggle function for
+ * notification listing sidebar.
+ * @return {Null}
+ */
+$.sidebar_toggle = function (action, target, container) {
+ var elem = '[data-toggle=sidebar]',
+ button,
+ containerOffsetLeft,
+ containerOffsetRight,
+ targetOffsetLeft,
+ targetOffsetRight,
+ targetWidth,
+ targetSide,
+ relationship,
+ pushType,
+ buttonParent;
+
+ var sidebar_window = {
+ update: function (target, container, button) {
+ containerOffsetLeft = $(container).data('offset-left') ? $(container).data('offset-left') : 0;
+ containerOffsetRight = $(container).data('offset-right') ? $(container).data('offset-right') : 0;
+ targetOffsetLeft = $(target).data('offset-left') ? $(target).data('offset-left') : 0;
+ targetOffsetRight = $(target).data('offset-right') ? $(target).data('offset-right') : 0;
+ targetWidth = $(target).data('width');
+ targetSide = $(target).data("side");
+ pushType = $(container).parent().is('body') == true ? 'padding' : 'margin';
+
+ if (button !== undefined) {
+ relationship = button.attr('rel') ? button.attr('rel') : '';
+ buttonParent = $(button).parent();
+ }
+ },
+
+ show: function () {
+ if ($(target).data('sidebar-fixed') == true) {
+ $(target).height($(window).height() - $(target).data('fixed-offset'));
+ }
+ $(target).trigger('show.sidebar');
+ if (targetWidth !== undefined) {
+ $(target).css('width', targetWidth);
+ }
+ $(target).addClass('toggled');
+ if (button !== undefined) {
+ if (relationship !== '') {
+ // Removing active class from all relative buttons
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').removeClass("active");
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').attr('aria-expanded', 'false');
+ }
+ // Adding active class to button
+ if (button.attr('data-handle') !== 'close') {
+ button.addClass("active");
+ button.attr('aria-expanded', 'true');
+ }
+ if (buttonParent.is('li')) {
+ if (relationship !== '') {
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().removeClass("active");
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().attr('aria-expanded', 'false');
+ }
+ buttonParent.addClass("active");
+ buttonParent.attr('aria-expanded', 'true');
+ }
+ }
+ // Sidebar open function
+ if (targetSide == 'left') {
+ if ((button !== undefined) && (button.attr('data-container-divide'))) {
+ $(container).css(pushType + '-' + targetSide, targetWidth + targetOffsetLeft);
+ }
+ $(target).css(targetSide, targetOffsetLeft);
+ } else if (targetSide == 'right') {
+ if ((button !== undefined) && (button.attr('data-container-divide'))) {
+ $(container).css(pushType + '-' + targetSide, targetWidth + targetOffsetRight);
+ }
+ $(target).css(targetSide, targetOffsetRight);
+ }
+ $(target).trigger('shown.sidebar');
+ },
+
+ hide: function () {
+ $(target).trigger('hide.sidebar');
+ $(target).removeClass('toggled');
+ if (button !== undefined) {
+ if (relationship !== '') {
+ // Removing active class from all relative buttons
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').removeClass("active");
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').attr('aria-expanded', 'false');
+ }
+ // Removing active class from button
+ if (button.attr('data-handle') !== 'close') {
+ button.removeClass("active");
+ button.attr('aria-expanded', 'false');
+ }
+ if ($(button).parent().is('li')) {
+ if (relationship !== '') {
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().removeClass("active");
+ $(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().attr('aria-expanded', 'false');
+ }
+ }
+ }
+ // Sidebar close function
+ if (targetSide == 'left') {
+ if ((button !== undefined) && (button.attr('data-container-divide'))) {
+ $(container).css(pushType + '-' + targetSide, targetOffsetLeft);
+ }
+ $(target).css(targetSide, -Math.abs(targetWidth + targetOffsetLeft));
+ } else if (targetSide == 'right') {
+ if ((button !== undefined) && (button.attr('data-container-divide'))) {
+ $(container).css(pushType + '-' + targetSide, targetOffsetRight);
+ }
+ $(target).css(targetSide, -Math.abs(targetWidth + targetOffsetRight));
+ }
+ $(target).trigger('hidden.sidebar');
+ }
+ };
+ if (action === 'show') {
+ sidebar_window.update(target, container);
+ sidebar_window.show();
+ }
+ if (action === 'hide') {
+ sidebar_window.update(target, container);
+ sidebar_window.hide();
+ }
+ // binding click function
+ var body = 'body';
+ $(body).off('click', elem);
+ $(body).on('click', elem, function (e) {
+ e.preventDefault();
+ button = $(this);
+ container = button.data('container');
+ target = button.data('target');
+ sidebar_window.update(target, container, button);
+ /**
+ * Sidebar function on data container divide
+ * @return {Null}
+ */
+ if (button.attr('aria-expanded') == 'false') {
+ sidebar_window.show();
+ } else if (button.attr('aria-expanded') == 'true') {
+ sidebar_window.hide();
+ }
+ });
+};
+
+$.fn.collapse_nav_sub = function () {
+ var navSelector = 'ul.nav';
+
+ if (!$(navSelector).hasClass('collapse-nav-sub')) {
+ $(navSelector + ' > li', this).each(function () {
+ var position = $(this).offset().left - $(this).parent().scrollLeft();
+ $(this).attr('data-absolute-position', (position + 5));
+ });
+
+ $(navSelector + ' li', this).each(function () {
+ if ($('ul', this).length !== 0) {
+ $(this).addClass('has-sub');
+ }
+ });
+
+ $(navSelector + ' > li', this).each(function () {
+ $(this).css({
+ 'left': $(this).data('absolute-position'),
+ 'position': 'absolute'
+ });
+ });
+
+ $(navSelector + ' li.has-sub', this).on('click', function () {
+ var elem = $(this);
+ if (elem.attr('aria-expanded') !== 'true') {
+ elem.siblings().fadeOut(100, function () {
+ elem.animate({'left': '15'}, 200, function () {
+ $(elem).first().children('ul').fadeIn(200);
+ });
+ });
+ elem.siblings().attr('aria-expanded', 'false');
+ elem.attr('aria-expanded', 'true');
+ } else {
+ $(elem).first().children('ul').fadeOut(100, function () {
+ elem.animate({'left': $(elem).data('absolute-position')}, 200, function () {
+ elem.siblings().fadeIn(100);
+ });
+ });
+ elem.siblings().attr('aria-expanded', 'false');
+ elem.attr('aria-expanded', 'false');
+ }
+ });
+
+ $(navSelector + ' > li.has-sub ul', this).on('click', function (e) {
+ e.stopPropagation();
+ });
+ $(navSelector).addClass('collapse-nav-sub');
+ }
+};
+
+$(".download-link").click(function(){
+ toggleEnrollment();
+});
+
+$(document).ready(function () {
+ $.sidebar_toggle();
+ if (typeof $.fn.collapse == 'function') {
+ $('.navbar-collapse.tiles').on('shown.bs.collapse', function () {
+ $(this).collapse_nav_sub();
+ });
+ }
+
+ loadNewNotificationsOnSideViewPanel();
+ $("#right-sidebar").on("click", ".new-notification", function () {
+ var notificationId = $(this).data("id");
+ var redirectUrl = $(this).data("url");
+ var markAsReadNotificationsEpr = emmAdminBasePath + "/notifications/" + notificationId + "/mark-checked";
+ var messageSideBar = ".sidebar-messages";
+
+ invokerUtil.put(
+ markAsReadNotificationsEpr,
+ null,
+ // on success
+ function (data) {
+ data = JSON.parse(data);
+ if (data.statusCode == responseCodes["ACCEPTED"]) {
+ location.href = redirectUrl;
+ }
+ },
+ // on error
+ function () {
+ var content = "Warning
" +
+ "Unexpected error occurred while loading notification. Please refresh the page and" +
+ " try again
";
+ $(messageSideBar).html(content);
+ }
+ );
+ });
+});
diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs
index 5b8e29dedf..b038011833 100644
--- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs
+++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/type-view.hbs
@@ -1,3 +1,6 @@
+{{unit "cdmf.unit.lib.qrcode"}}
+{{unit "cdmf.unit.device.type.android.qr-modal"}}
+
Android Mobile
@@ -22,19 +25,17 @@
- STEP 01 Android
- Mobile.
+ Mobile.
- STEP 02 Go ahead
- and click [Enroll Device].
+ and click [Enroll Device].
- STEP 03 Proceed
- to the [Prepare] section.
+ to the [Prepare] section.
-
-
Enroll Device
-
+
Enroll Device
@@ -60,39 +61,10 @@
-
-
-
-
-
-
Scan QR code to start enrollment
-
Please scan the QR code using your mobile device to retrieve enrollment URL.
-
-
-
-
-
-
{{#zone "topCss"}}
{{css "css/styles.css"}}
{{/zone}}
{{#zone "bottomJs"}}
-
+ {{js "js/type-view.js"}}
{{/zone}}
\ No newline at end of file
diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/operation-bar.json b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/operation-bar.json
index 56a988c763..688e939808 100644
--- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/operation-bar.json
+++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar/operation-bar.json
@@ -1,4 +1,3 @@
{
- "version": "1.0.0",
- "extends": "cdmf.unit.device.operation-bar"
+ "version": "1.0.0"
}
\ No newline at end of file
diff --git a/features/device-types-feature/androidsense-plugin-feature/org.wso2.carbon.device.mgt.iot.androidsense.feature/src/main/resources/devicetypes/android_sense.xml b/features/device-types-feature/androidsense-plugin-feature/org.wso2.carbon.device.mgt.iot.androidsense.feature/src/main/resources/devicetypes/android_sense.xml
index 3a0eafe7ff..c4e70a7684 100644
--- a/features/device-types-feature/androidsense-plugin-feature/org.wso2.carbon.device.mgt.iot.androidsense.feature/src/main/resources/devicetypes/android_sense.xml
+++ b/features/device-types-feature/androidsense-plugin-feature/org.wso2.carbon.device.mgt.iot.androidsense.feature/src/main/resources/devicetypes/android_sense.xml
@@ -57,7 +57,7 @@
androidsense.mqtt.adapter
- tcp://localhost:1883
+ tcp://localhost:1886
admin
https://localhost:9443/dynamic-client-web/register
0
diff --git a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/devicetypes/raspberrypi.xml b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/devicetypes/raspberrypi.xml
index d9fcb23ab7..5829b24d65 100644
--- a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/devicetypes/raspberrypi.xml
+++ b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/devicetypes/raspberrypi.xml
@@ -39,7 +39,7 @@
raspberrypi.mqtt.adapter
- tcp://localhost:1883
+ tcp://localhost:1886
admin
https://localhost:9443/dynamic-client-web/register
0
diff --git a/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/conf/virtual_firealarm.xml b/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/conf/virtual_firealarm.xml
index 6481df82cd..9cef7c1387 100644
--- a/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/conf/virtual_firealarm.xml
+++ b/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/conf/virtual_firealarm.xml
@@ -23,7 +23,7 @@
MQTT
virtualfirealarm.mqtt.adapter
- tcp://localhost:1883
+ tcp://localhost:1886
admin
https://localhost:9443/dynamic-client-web/register
0
diff --git a/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/devicetypes/virtual_firealarm.xml b/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/devicetypes/virtual_firealarm.xml
index d95c194bf5..a92d4e0c1d 100644
--- a/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/devicetypes/virtual_firealarm.xml
+++ b/features/device-types-feature/virtual-fire-alarm-plugin-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/devicetypes/virtual_firealarm.xml
@@ -39,7 +39,7 @@
virtualfirealarm.mqtt.adapter
- tcp://localhost:1883
+ tcp://localhost:1886
admin
https://localhost:9443/dynamic-client-web/register
0
diff --git a/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/pom.xml b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/pom.xml
new file mode 100644
index 0000000000..d3118d5f2f
--- /dev/null
+++ b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ extensions-feature
+ 2.2.6-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature
+ pom
+ WSO2 Carbon - MQTT Authorization Feature
+ http://wso2.org
+ This feature contains the bundles required for mqtt authorization
+
+
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.p2.category.type:server
+ org.eclipse.equinox.p2.type.group:true
+
+
+
+
+ org.wso2.carbon.devicemgt-plugins:org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization:${carbon.devicemgt.plugins.version}
+
+
+
+ org.wso2.carbon.core.server:4.4.9
+
+
+
+
+
+
+
+
diff --git a/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/build.properties b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/build.properties
new file mode 100644
index 0000000000..ddedd58dc4
--- /dev/null
+++ b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/build.properties
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+#
+# WSO2 Inc. licenses this file to you under the Apache License,
+# Version 2.0 (the "License"); you may not use this file except
+# in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+custom = true
diff --git a/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/p2.inf b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/p2.inf
new file mode 100644
index 0000000000..7ab37b9d7d
--- /dev/null
+++ b/features/extensions-feature/org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature/src/main/resources/p2.inf
@@ -0,0 +1 @@
+instructions.configure = \
\ No newline at end of file
diff --git a/features/extensions-feature/pom.xml b/features/extensions-feature/pom.xml
index dd2de92bbd..8b3e4aed41 100644
--- a/features/extensions-feature/pom.xml
+++ b/features/extensions-feature/pom.xml
@@ -36,6 +36,7 @@
org.wso2.carbon.appmgt.mdm.osgiconnector.feature
org.wso2.carbon.device.mgt.adapter.feature
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.feature
diff --git a/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/datasources/android-datasources.xml b/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/datasources/android-datasources.xml
index f380352207..a0c8b03930 100644
--- a/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/datasources/android-datasources.xml
+++ b/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/datasources/android-datasources.xml
@@ -30,7 +30,7 @@
- jdbc:h2:repository/database/Android_DB;DB_CLOSE_ON_EXIT=FALSE
+ jdbc:h2:repository/database/WSO2MobileAndroid_DB;DB_CLOSE_ON_EXIT=FALSE
wso2carbon
wso2carbon
diff --git a/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml b/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml
index 65199a080d..f1fdb6cc4e 100644
--- a/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml
+++ b/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml
@@ -19,6 +19,8 @@
-->
+
+
en_US
1.0.0
@@ -37,7 +39,6 @@
DEVICE_ID
- DEVICE_ID
GCM_TOKEN
DEVICE_INFO
IMEI
@@ -57,16 +58,10 @@
-
- abc
- this is a feature
-
-
- deviceId
-
-
- test
-
+
+ Ring
+ Ring the device
+
diff --git a/pom.xml b/pom.xml
index 248afa466b..27724bdbbf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1139,6 +1139,22 @@
org.wso2.carbon.apimgt.keymgt.client
${carbon.api.mgt.version}
+
+
+ org.wso2.andes.wso2
+ andes
+ ${carbon.messaging.version}
+
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization
+ ${carbon.devicemgt.plugins.version}
+
+
+ commons-lang
+ commons-lang
+ ${commons.lang.version}
+
@@ -1245,6 +1261,7 @@
1.0.8
1.8
0.9.1
+ 2.2
3.1.0.wso2v2
@@ -1297,6 +1314,9 @@
5.0.2.Final
[0.0.0,1.0.0)
+
+
+ 3.1.11