Merge branch 'release-2.0.x' of https://github.com/milanperera/carbon-device-mgt into release-2.0.x

revert-70aa11f8
GPrathap 8 years ago
commit 05adba3978

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Annotations</name>
<description>WSO2 Carbon - API Management Custom Annotation Module</description>

@ -21,12 +21,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - API Application Management API</name>

@ -22,12 +22,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Application Management</name>

@ -75,16 +75,9 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
"Api application creation failed for " + applicationName + " to the user " + username);
}
APIKey retrievedApiApplicationKey = null;
for (APIKey apiKey : application.getKeys()) {
String applicationKeyType = apiKey.getType();
if (applicationKeyType != null && applicationKeyType.equals(keyType)) {
retrievedApiApplicationKey = apiKey;
break;
}
}
if (retrievedApiApplicationKey != null) {
if (retrievedApiApplicationKey.getConsumerKey().equals(clientId)) {
OAuthApplicationInfo oAuthApp = application.getOAuthApp(keyType);
if (oAuthApp != null) {
if (oAuthApp.getClientId().equals(clientId)) {
if (tags != null && tags.length > 0) {
createApplicationAndSubscribeToAPIs(applicationName, tags, username);
}
@ -131,7 +124,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
* {@inheritDoc}
*/
@Override
public ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[],
public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[],
String keyType, String username,
boolean isAllowedAllDomains, String validityTime)
throws APIManagerException {
@ -152,18 +145,11 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
"Api application creation failed for " + apiApplicationName + " to the user " + username);
}
APIKey retrievedApiApplicationKey = null;
for (APIKey apiKey : application.getKeys()) {
String applicationKeyType = apiKey.getType();
if (applicationKeyType != null && applicationKeyType.equals(keyType)) {
retrievedApiApplicationKey = apiKey;
break;
}
}
if (retrievedApiApplicationKey != null) {
OAuthApplicationInfo oAuthApp = application.getOAuthApp(keyType);
if (oAuthApp != null) {
ApiApplicationKey apiApplicationKey = new ApiApplicationKey();
apiApplicationKey.setConsumerKey(retrievedApiApplicationKey.getConsumerKey());
apiApplicationKey.setConsumerSecret(retrievedApiApplicationKey.getConsumerSecret());
apiApplicationKey.setConsumerKey(oAuthApp.getClientId());
apiApplicationKey.setConsumerSecret(oAuthApp.getClientSecret());
return apiApplicationKey;
}
String[] allowedDomains = new String[1];

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Webapp Publisher</name>
<description>WSO2 Carbon - API Management Webapp Publisher</description>

@ -75,7 +75,7 @@ public class APIPublisherUtil {
api.setUrl(config.getEndpoint());
api.addAvailableTiers(provider.getTiers());
api.setEndpointSecured(true);
api.setEndpointSecured(false);
api.setStatus(APIStatus.CREATED);
api.setTransports(config.getTransports());
api.setApiLevelPolicy(config.getPolicy());
@ -261,18 +261,7 @@ public class APIPublisherUtil {
}
apiConfig.setOwner(owner);
String isSecuredParam = servletContext.getInitParameter(PARAM_MANAGED_API_IS_SECURED);
boolean isSecured;
if (isSecuredParam == null || isSecuredParam.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("'managed-api-isSecured' attribute is not configured. Therefore, using the default, " +
"which is 'true'");
}
isSecured = false;
} else {
isSecured = Boolean.parseBoolean(isSecuredParam);
}
apiConfig.setSecured(isSecured);
apiConfig.setSecured(false);
String transports = servletContext.getInitParameter(PARAM_MANAGED_API_TRANSPORTS);
if (transports == null || transports.isEmpty()) {

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apimgt-extensions</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - API Management Extensions Component</name>
<url>http://wso2.org</url>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,13 +21,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Certificate Management Core</name>
<description>WSO2 Carbon - Certificate Management Core</description>

@ -22,14 +22,14 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Certificate Management Component</name>
<url>http://wso2.org</url>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.extensions.device.type.deployer.template;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
@ -41,6 +42,7 @@ import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.util.
import org.wso2.carbon.device.mgt.extensions.license.mgt.registry.RegistryBasedLicenseManager;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
@ -118,6 +120,12 @@ public class DeviceTypeManager implements DeviceManager {
throw new DeviceTypeDeployerFileException("Could not find definition for table: " + tableName);
}
propertiesExist = true;
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext()
.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true);
DeviceDAODefinition deviceDAODefinition = new DeviceDAODefinition(deviceDefinitionTable);
String datasourceName = deviceTypeConfiguration.getDataSource().getJndiConfig().getName();
if (datasourceName != null && !datasourceName.isEmpty()) {
@ -138,6 +146,9 @@ public class DeviceTypeManager implements DeviceManager {
} else {
throw new DeviceTypeDeployerFileException("Invalid datasource name.");
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
}
}

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>carbon-devicemgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -3,7 +3,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -143,7 +143,7 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.user.mgt</artifactId>
<scope>provided</scope>
<exclusions>
@ -190,7 +190,7 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
<scope>provided</scope>
<exclusions>

@ -0,0 +1,56 @@
/*
* 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.device.mgt.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult;
import java.util.ArrayList;
import java.util.List;
public class DeviceToGroupsAssignment extends BasePaginatedResult {
@ApiModelProperty(value = "List of device group ids.")
@JsonProperty("deviceGroupIds")
private List<Integer> deviceGroupIds = new ArrayList<>();
@ApiModelProperty(value = "Device identifier of the device needed to be assigned with group")
@JsonProperty("deviceIdentifier")
private DeviceIdentifier deviceIdentifier;
public List<Integer> getDeviceGroupIds() {
return deviceGroupIds;
}
public void setDeviceGroupIds(List<Integer> deviceGroupIds) {
this.deviceGroupIds = deviceGroupIds;
}
public DeviceIdentifier getDeviceIdentifier() {
return deviceIdentifier;
}
public void setDeviceIdentifier(DeviceIdentifier deviceIdentifier) {
this.deviceIdentifier = deviceIdentifier;
}
}

@ -0,0 +1,50 @@
/*
* 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.device.mgt.jaxrs.beans;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel(value = "EnrollmentInvitation", description = "Holds data to send enrollment invitation to list of recipients.")
public class EnrollmentInvitation {
@ApiModelProperty(name = "deviceType", value = "Device type name.", required = true)
private String deviceType;
@ApiModelProperty(name = "recipients", value = "List of recipients.", required = true)
private List<String> recipients;
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public List<String> getRecipients() {
return recipients;
}
public void setRecipients(List<String> recipients) {
this.recipients = recipients;
}
}

@ -5,24 +5,50 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.AuthorizationScope;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.device.mgt.analytics.dashboard.bean.DeviceCountByGroup;
import org.wso2.carbon.device.mgt.jaxrs.beans.DashboardGadgetDataWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.DashboardPaginationGadgetDataWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* Device Analytics Dashboard related REST-APIs. This can be used to obtain device related analytics.
*/
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "DeviceAnalyticsDashboard"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/dashboard"),
})
}
),
tags = {
@Tag(name = "device_management", description = "Device Analytics Dashboard related APIs.")
}
)
@Path("/dashboard")
@Api(value = "Device Analytics Dashboard",
description = "Device Analytics Dashboard related information APIs are described here.")
@Produces(MediaType.APPLICATION_JSON)
@SuppressWarnings("NonJaxWsWebServices")
@Consumes(MediaType.APPLICATION_JSON)
public interface Dashboard {
String CONNECTIVITY_STATUS = "connectivity-status";
@ -40,10 +66,17 @@ public interface Dashboard {
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get the details of registered devices in WSO2 EMM.",
value = "Get the details of registered devices in WSO2 IoT.",
notes = "Get the details of active, inactive, removed and total number of registered devices in"
+ " WSO2 EMM.",
tags = "Dashboard")
+ " WSO2 IoT.",
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -92,8 +125,15 @@ public interface Dashboard {
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get the number of unmonitored and non-compliant devices in WSO2 EMM.",
tags = "Dashboard")
value = "Get the number of unmonitored and non-compliant devices in WSO2 IoT.",
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -144,7 +184,14 @@ public interface Dashboard {
httpMethod = "GET",
value = "Get the number of devices that have not complied to a policy that was enforced on a "
+ "device.",
tags = "Dashboard")
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -208,7 +255,14 @@ public interface Dashboard {
httpMethod = "GET",
value = "Get the number of devices for a given device type, such as connectivity status, "
+ "potential vulnerability, platform, and ownership.\n",
tags = "Dashboard")
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -254,11 +308,11 @@ public interface Dashboard {
@ApiParam(
name = "connectivity-status",
value = "Provide the connectivity status of the device. The following values can be assigned:\n"
+ "active: The devices that are registered with WSO2 EMM and are actively "
+ "active: The devices that are registered with WSO2 IoT and are actively "
+ "communicating with the server.\n"
+ "inactive: The devices that are registered with WSO2 EMM but unable to "
+ "inactive: The devices that are registered with WSO2 IoT but unable to "
+ "actively communicate with the server.\n"
+ "removed: The devices that have unregistered from WSO2 EMM",
+ "removed: The devices that have unregistered from WSO2 IoT",
required = true)
@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
@ApiParam(
@ -266,7 +320,7 @@ public interface Dashboard {
value = "Provide details of the potential vulnerabilities of the device. The following "
+ "values can be assigned:\n"
+ "non-compliant: Devices that have not complied to the policies enforced on the "
+ "device by WSO2 EMM.\n"
+ "device by WSO2 IoT.\n"
+ "unmonitored: Devices that have no policy assigned to them.",
required = true)
@QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability,
@ -291,7 +345,14 @@ public interface Dashboard {
httpMethod = "GET",
value = "Get the number of devices that have not complied to a given policy based on a particular"
+ " device type.",
tags = "Dashboard")
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -359,12 +420,19 @@ public interface Dashboard {
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get the number of devices that are registered with WSO2 EMM filtered by one of the "
value = "Get the number of devices that are registered with WSO2 IoT filtered by one of the "
+ "following attributes:\n"
+ "Connectivity status of the device, such as active, inactive or removed.\n"
+ "The device ownership type, such as BYOD or COPE.\n" + "The device platform.\n"
+ "The potential vulnerabilities faced by the devices.",
tags = "Dashboard")
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -411,12 +479,12 @@ public interface Dashboard {
name = "connectivity-status",
value = "Provide the connectivity status of the device. You can assign any of the values "
+ "given below:\n"
+ "Total: All the devices that have registered with WSO2 EMM.\n"
+ "active: The devices that are registered with WSO2 EMM and are actively "
+ "Total: All the devices that have registered with WSO2 IoT.\n"
+ "active: The devices that are registered with WSO2 IoT and are actively "
+ "communicating with the server.\n"
+ "inactive: The devices that are registered with WSO2 EMM but unable to actively"
+ "inactive: The devices that are registered with WSO2 IoT but unable to actively"
+ " communicate with the server.\n"
+ "removed: The devices that have unregistered from WSO2 EMM.",
+ "removed: The devices that have unregistered from WSO2 IoT.",
required = true)
@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
@ApiParam(
@ -424,7 +492,7 @@ public interface Dashboard {
value = "Provide details of the potential vulnerabilities of the device. You can assign"
+ " any of the values given below:\n"
+ "non-compliant: Devices that have not complied to the policies enforced on the "
+ "device by WSO2 EMM.\n"
+ "device by WSO2 IoT.\n"
+ "unmonitored: Devices that have no policy assigned to them.",
required = true)
@QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability,
@ -449,8 +517,15 @@ public interface Dashboard {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get the number of devices that have not complied to a given policy over the total"
+ " number of devices registered with WSO2 EMM.\n",
tags = "Dashboard")
+ " number of devices registered with WSO2 IoT.\n",
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -519,7 +594,14 @@ public interface Dashboard {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get device details of devices based on a particular device type.",
tags = "Dashboard")
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,
@ -565,19 +647,19 @@ public interface Dashboard {
@ApiParam(
name = "connectivity-status",
value = "Provide the connectivity status of the device. This can be one of the following:\n"
+ "Total: All the devices that have registered with WSO2 EMM.\n"
+ "active: The devices that are registered with WSO2 EMM and are actively "
+ "Total: All the devices that have registered with WSO2 IoT.\n"
+ "active: The devices that are registered with WSO2 IoT and are actively "
+ "communicating with the server.\n"
+ "inactive: The devices that are registered with WSO2 EMM but unable to actively"
+ "inactive: The devices that are registered with WSO2 IoT but unable to actively"
+ " communicate with the server.\n"
+ "removed: The devices that have unregistered from WSO2 EMM.",
+ "removed: The devices that have unregistered from WSO2 IoT.",
required = true)
@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
@ApiParam(
name = "potential-vulnerability",
value = "Provide details of the potential vulnerabilities of the device. This can be:\n"
+ "non-compliant: Devices that have not complied to the policies enforced on "
+ "the device by WSO2 EMM.\n"
+ "the device by WSO2 IoT.\n"
+ "unmonitored: Devices that have no policy assigned to them. ",
required = true)
@QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability,
@ -615,7 +697,14 @@ public interface Dashboard {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get device details of non-compliant devices which do not comply to a given policy.",
tags = "Dashboard")
tags = "Dashboard",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/dashboard/view",
description = "View Dashboard")}
)
})
@ApiResponses(value = {
@ApiResponse(
code = 200,

@ -37,6 +37,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList;
@ -774,4 +775,115 @@ public interface GroupManagementService {
required = true)
@Valid List<DeviceIdentifier> deviceIdentifiers);
@Path("/device/assign")
@POST
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Assign devices to groups",
notes = "Add existing device to device groups.",
tags = "Device Group Management",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/groups/devices/add",
description = "Add devices")}
)
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully assign the device to groups.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the client has already the latest version of " +
"the requested resource."),
@ApiResponse(
code = 404,
message = "No groups found.",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while adding devices to the group.",
response = ErrorResponse.class)
})
Response updateDeviceAssigningToGroups(
@ApiParam(
name = "deviceToGroupsAssignment",
value = "Device to groups assignment",
required = true)
@Valid DeviceToGroupsAssignment deviceToGroupsAssignment);
@Path("/device")
@GET
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_GET,
value = "List of groups that have the device",
notes = "List of groups that have the device.",
tags = "Device Group Management",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/groups/devices/view",
description = "Add devices")}
)
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the client has already the latest version of " +
"the requested resource."),
@ApiResponse(
code = 404,
message = "No groups found.",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred.",
response = ErrorResponse.class)
})
Response getGroups(
@ApiParam(
name = "deviceId",
value = "Id of the device.")
@QueryParam("deviceId") String deviceId,
@ApiParam(
name = "deviceType",
value = "Type of the device.")
@QueryParam("deviceType") String deviceType);
}

@ -562,5 +562,8 @@ public interface PolicyManagementService {
required = true)
List<PriorityUpdatedPolicyWrapper> priorityUpdatedPolicies);
@GET
@Path("/effective-policy/{deviceType}/{deviceId}")
Response getEffectivePolicy(@PathParam("deviceId") String deviceId, @PathParam("deviceType") String deviceType);
}

@ -18,22 +18,39 @@
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Info;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Extension;
import io.swagger.annotations.Tag;
import io.swagger.annotations.Api;
import io.swagger.annotations.AuthorizationScope;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import io.swagger.annotations.AuthorizationScope;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import org.wso2.carbon.device.mgt.jaxrs.beans.*;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.apache.axis2.transport.http.HTTPConstants;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList;
import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList;
import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo;
import javax.ws.rs.*;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@ -65,7 +82,7 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Adding a User",
notes = "WSO2 EMM supports user management. Add a new user to the WSO2 EMM user management system via this REST API",
notes = "WSO2 IoTS supports user management. Add a new user to the WSO2 IoTS user management system via this REST API",
tags = "User Management",
authorizations = {
@Authorization(
@ -126,7 +143,7 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Details of a User",
notes = "Get the details of a user registered with WSO2 EMM using the REST API.",
notes = "Get the details of a user registered with WSO2 IoTS using the REST API.",
response = BasicUserInfo.class,
tags = "User Management",
authorizations = {
@ -267,7 +284,7 @@ public interface UserManagementService {
@ApiOperation(
httpMethod = "DELETE",
value = "Deleting a User",
notes = "When an employee leaves the organization, you can remove the user details from WSO2 EMM using this REST API.",
notes = "When an employee leaves the organization, you can remove the user details from WSO2 IoTS using this REST API.",
tags = "User Management",
authorizations = {
@Authorization(
@ -280,7 +297,7 @@ public interface UserManagementService {
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully removed the user from WSO2 EMM."),
message = "OK. \n Successfully removed the user from WSO2 IoTS."),
@ApiResponse(
code = 404,
message = "Not Found. \n The specified resource does not exist.",
@ -312,7 +329,7 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting the Role Details of a User",
notes = "A user can be assigned to one or more role in EMM. Using this REST API you can get the role/roles a user is assigned to.",
notes = "A user can be assigned to one or more role in IoTS. Using this REST API you can get the role/roles a user is assigned to.",
tags = "User Management",
authorizations = {
@Authorization(
@ -375,7 +392,7 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Details of Users",
notes = "You are able to manage users in WSO2 EMM by adding, updating and removing users. If you wish to get the list of users registered with WSO2 EMM, you can do so "
notes = "You are able to manage users in WSO2 IoTS by adding, updating and removing users. If you wish to get the list of users registered with WSO2 IoTS, you can do so "
+ "using this REST API",
tags = "User Management",
authorizations = {
@ -389,7 +406,7 @@ public interface UserManagementService {
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the list of users registered with WSO2 EMM.",
message = "OK. \n Successfully fetched the list of users registered with WSO2 IoTS.",
response = BasicUserInfoList.class,
responseHeaders = {
@ResponseHeader(
@ -414,7 +431,7 @@ public interface UserManagementService {
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the list of WSO2 EMM users.",
message = "Internal Server Error. \n Server error occurred while fetching the list of WSO2 IoTS users.",
response = ErrorResponse.class)
})
Response getUsers(
@ -449,7 +466,7 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting the User Count",
notes = "Get the number of users in WSO2 EMM via this REST API.",
notes = "Get the number of users in WSO2 IoTS via this REST API.",
tags = "User Management",
authorizations = {
@Authorization(
@ -474,7 +491,7 @@ public interface UserManagementService {
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the total number of users in WSO2 EMM.",
message = "Internal Server Error. \n Server error occurred while fetching the total number of users in WSO2 IoTS.",
response = ErrorResponse.class)
})
Response getUserCount();
@ -608,7 +625,7 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "Changing the User Password",
notes = "A user is able to change the password to secure their WSO2 EMM profile via this REST API.",
notes = "A user is able to change the password to secure their WSO2 IoTS profile via this REST API.",
tags = "User Management",
authorizations = {
@Authorization(
@ -653,8 +670,8 @@ public interface UserManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Sending Enrollment Invitations to Users",
notes = "Send the users a mail inviting them to download the EMM mobile application on their devices using the REST API given below.\n" +
"Before running the REST API command to send the enrollment invitations to users make sure to configure WSO2 EMM as explained in step 4, under the WSO2 EMM general server configurations documentation.",
notes = "Send the users a mail inviting them to enroll their devices using the REST API given below.\n" +
"Before running the REST API command to send the enrollment invitations to users make sure to configure WSO2 IoTS as explained in step 4, under the WSO2 IoTS general server configurations documentation.",
tags = "User Management",
authorizations = {
@Authorization(
@ -691,4 +708,47 @@ public interface UserManagementService {
value = "List of users",
required = true) List<String> usernames);
@POST
@Path("/enrollment-invite")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HTTPConstants.HEADER_POST,
value = "Sending Enrollment Invitations to email address",
notes = "Send the a mail inviting recipients to enroll devices.",
tags = "User Management",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(scope = "/device-mgt/users/invite", description = "Invite Users")}
)
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully sent the invitation mail."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n The specified resource does not exist.\n",
response = ErrorResponse.class),
@ApiResponse(
code = 415,
message = "Unsupported media type. \n The format of the requested entity was not supported.\n",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while updating the user credentials.",
response = ErrorResponse.class)
})
Response inviteToEnrollDevice(
@ApiParam(
name = "enrollmentInvitation",
value = "List of email address of recipients",
required = true)
@Valid EnrollmentInvitation enrollmentInvitation);
}

@ -45,6 +45,7 @@ import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.common.monitor.ComplianceData;
import org.wso2.carbon.policy.mgt.common.monitor.PolicyComplianceException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.validation.constraints.Size;
import javax.ws.rs.*;
@ -113,15 +114,16 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
}
// this is the user who initiates the request
String authorizedUser = CarbonContext.getThreadLocalCarbonContext().getUsername();
String authorizedUser = MultitenantUtils.getTenantAwareUsername(CarbonContext.getThreadLocalCarbonContext().getUsername());
// check whether the user is device-mgt admin
if (deviceAccessAuthorizationService.isDeviceAdminUser()) {
if (user != null && !user.isEmpty()) {
request.setOwner(user);
request.setOwner(MultitenantUtils.getTenantAwareUsername(user));
}
} else {
if (user != null && !user.isEmpty()) {
user = MultitenantUtils.getTenantAwareUsername(user);
if (user.equals(authorizedUser)) {
request.setOwner(user);
} else {

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
@ -35,12 +36,14 @@ import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment;
import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList;
import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
public class GroupManagementServiceImpl implements GroupManagementService {
@ -243,7 +246,8 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
}
@Override public Response removeDevicesFromGroup(int groupId, List<DeviceIdentifier> deviceIdentifiers) {
@Override
public Response removeDevicesFromGroup(int groupId, List<DeviceIdentifier> deviceIdentifiers) {
try {
DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers);
return Response.status(Response.Status.OK).build();
@ -256,4 +260,45 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
}
@Override
public Response updateDeviceAssigningToGroups(DeviceToGroupsAssignment deviceToGroupsAssignment) {
try {
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
deviceIdentifiers.add(deviceToGroupsAssignment.getDeviceIdentifier());
GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService();
List<DeviceGroup> deviceGroups = service.getGroups(deviceToGroupsAssignment.getDeviceIdentifier());
for (DeviceGroup group : deviceGroups) {
Integer groupId = group.getGroupId();
if (deviceToGroupsAssignment.getDeviceGroupIds().contains(groupId)) {
deviceToGroupsAssignment.getDeviceGroupIds().remove(groupId);
} else if (!CarbonConstants.REGISTRY_SYSTEM_USERNAME.equals(group.getOwner())) {
DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers);
}
}
for (int groupId : deviceToGroupsAssignment.getDeviceGroupIds()) {
DeviceMgtAPIUtils.getGroupManagementProviderService().addDevices(groupId, deviceIdentifiers);
}
return Response.status(Response.Status.OK).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while assigning device to groups.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (DeviceNotFoundException e) {
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
}
}
@Override
public Response getGroups(String deviceId, String deviceType) {
try {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType);
List<DeviceGroup> deviceGroups = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroups(deviceIdentifier);
return Response.status(Response.Status.OK).entity(deviceGroups).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while removing devices from group.";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
}

@ -373,4 +373,29 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
}
}
@GET
@Path("/effective-policy/{deviceType}/{deviceId}")
@Override
public Response getEffectivePolicy(@PathParam("deviceId") String deviceId, @PathParam("deviceType") String deviceType) {
PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService();
final org.wso2.carbon.policy.mgt.common.Policy policy;
try {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(deviceType);
policy = policyManagementService.getAppliedPolicyToDevice(deviceIdentifier);
if (policy == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(
"No policy found for device ID '" + deviceId + "'"+ deviceId).build()).build();
}
} catch (PolicyManagementException e) {
String msg = "Error occurred while retrieving policy corresponding to the id '" + deviceType + "'"+ deviceId;
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity(policy).build();
}
}

@ -143,6 +143,17 @@ public class RoleManagementServiceImpl implements RoleManagementService {
}
}
private UIPermissionNode getAllRolePermissions(String roleName, UserRealm userRealm) throws UserAdminException {
org.wso2.carbon.user.core.UserRealm userRealmCore = null;
if (userRealm instanceof org.wso2.carbon.user.core.UserRealm) {
userRealmCore = (org.wso2.carbon.user.core.UserRealm) userRealm;
}
final UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore);
final UIPermissionNode rolePermissions =
userRealmProxy.getRolePermissions(roleName, MultitenantConstants.SUPER_TENANT_ID);
return rolePermissions;
}
private UIPermissionNode getUIPermissionNode(String roleName, UserRealm userRealm)
throws UserAdminException {
org.wso2.carbon.user.core.UserRealm userRealmCore = null;
@ -228,6 +239,19 @@ public class RoleManagementServiceImpl implements RoleManagementService {
return list;
}
private List<String> getAuthorizedPermissions(UIPermissionNode uiPermissionNode, List<String> list) {
for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) {
if (permissionNode.isSelected()) {
list.add(permissionNode.getResourcePath());
}
if (permissionNode.getNodeList() != null && permissionNode.getNodeList().length > 0) {
getAuthorizedPermissions(permissionNode, list);
}
}
return list;
}
@POST
@Override
public Response addRole(RoleInfo roleInfo) {
@ -377,6 +401,17 @@ public class RoleManagementServiceImpl implements RoleManagementService {
}
if (roleInfo.getPermissions() != null) {
// Get all role permissions
final UIPermissionNode rolePermissions = this.getAllRolePermissions(roleName, userRealm);
List<String> permissions = new ArrayList<String>();
this.getAuthorizedPermissions(rolePermissions, permissions);
for (String permission : roleInfo.getPermissions()) {
permissions.add(permission);
}
String [] allApplicablePerms = new String[permissions.size()];
allApplicablePerms = permissions.toArray(allApplicablePerms);
roleInfo.setPermissions(allApplicablePerms);
// Delete all authorizations for the current role before authorizing the permission tree
authorizationManager.clearRoleAuthorization(roleName);
if (roleInfo.getPermissions().length > 0) {
@ -394,6 +429,11 @@ public class RoleManagementServiceImpl implements RoleManagementService {
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (UserAdminException e) {
String msg = "Error occurred while updating permissions of the role '" + roleName + "'";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}

@ -23,9 +23,16 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.wst.common.uriresolver.internal.util.URIEncoder;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo;
import org.wso2.carbon.device.mgt.jaxrs.beans.*;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo;
import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList;
import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList;
import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo;
import org.wso2.carbon.device.mgt.jaxrs.service.api.UserManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
@ -33,15 +40,33 @@ import org.wso2.carbon.device.mgt.jaxrs.util.CredentialManagementResponseBuilder
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import javax.ws.rs.*;
import org.wso2.carbon.utils.CarbonUtils;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.SecureRandom;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@ -446,7 +471,7 @@ public class UserManagementServiceImpl implements UserManagementService {
* @param usernames Username list of the users to be invited
*/
@POST
@Path("send-invitation")
@Path("/send-invitation")
@Produces({MediaType.APPLICATION_JSON})
public Response inviteExistingUsersToEnrollDevice(List<String> usernames) {
if (log.isDebugEnabled()) {
@ -462,7 +487,8 @@ public class UserManagementServiceImpl implements UserManagementService {
props.setProperty("username", username);
EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props);
dms.sendEnrolmentInvitation(metaInfo);
dms.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE,
metaInfo);
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while inviting user to enrol their device";
@ -476,6 +502,40 @@ public class UserManagementServiceImpl implements UserManagementService {
return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build();
}
@POST
@Path("/enrollment-invite")
@Override
public Response inviteToEnrollDevice(EnrollmentInvitation enrollmentInvitation) {
if (log.isDebugEnabled()) {
log.debug("Sending enrollment invitation mail to existing user.");
}
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
try {
Set<String> recipients = new HashSet<>();
for (String recipient : enrollmentInvitation.getRecipients()) {
recipients.add(recipient);
}
Properties props = new Properties();
String username = DeviceMgtAPIUtils.getAuthenticatedUser();
String firstName = getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME);
if (firstName == null) {
firstName = username;
}
props.setProperty("first-name", firstName);
props.setProperty("device-type", enrollmentInvitation.getDeviceType());
EmailMetaInfo metaInfo = new EmailMetaInfo(recipients, props);
dms.sendEnrolmentInvitation(getEnrollmentTemplateName(enrollmentInvitation.getDeviceType()), metaInfo);
} catch (DeviceManagementException e) {
String msg = "Error occurred while inviting user to enrol their device";
log.error(msg, e);
} catch (UserStoreException e) {
String msg = "Error occurred while getting claim values to invite user";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build();
}
private Map<String, String> buildDefaultUserClaims(String firstName, String lastName, String emailAddress) {
Map<String, String> defaultUserClaims = new HashMap<>();
@ -522,4 +582,19 @@ public class UserManagementServiceImpl implements UserManagementService {
return userStoreManager.getUserClaimValue(username, claimUri, null);
}
private String getEnrollmentTemplateName(String deviceType) {
String templateName = deviceType + "-enrollment-invitation";
File template = new File(CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator
+ "resources" + File.separator + "email-templates" + File.separator + templateName
+ ".vm");
if (template.exists()) {
return templateName;
} else {
if (log.isDebugEnabled()) {
log.debug("The template that is expected to use is not available. Therefore, using default template.");
}
}
return DeviceManagementConstants.EmailAttributes.DEFAULT_ENROLLMENT_TEMPLATE;
}
}

@ -286,4 +286,14 @@ public class DeviceMgtAPIUtils {
}
}
public static String getAuthenticatedUser() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
String username = threadLocalCarbonContext.getUsername();
String tenantDomain = threadLocalCarbonContext.getTenantDomain();
if (username != null && username.endsWith(tenantDomain)) {
return username.substring(0, username.lastIndexOf("@"));
}
return username;
}
}

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -52,6 +52,6 @@ public class OperationMonitoringTaskConfig {
public void setMonitoringOperation(List<MonitoringOperation> monitoringOperation) {
this.monitoringOperation = monitoringOperation;
}
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -206,17 +206,37 @@
<dependency>
<groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.apimgt.api</artifactId>
<exclusions>
<exclusion>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.user.mgt.stub</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.user.mgt</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.apimgt.impl</artifactId>
<exclusions>
<exclusion>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.user.mgt.stub</artifactId>
</exclusion>
<exclusion>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.user.mgt</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.axis2.wso2</groupId>
<artifactId>axis2</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
</dependency>
<dependency>

@ -75,6 +75,10 @@ public final class DeviceManagementConstants {
public static final String SERVER_BASE_URL_HTTPS = "base-url-https";
public static final String SERVER_BASE_URL_HTTP = "base-url-http";
public static final String DOWNLOAD_URL = "download-url";
public static final String USER_REGISTRATION_TEMPLATE = "user-registration";
public static final String USER_ENROLLMENT_TEMPLATE = "user-enrollment";
public static final String DEFAULT_ENROLLMENT_TEMPLATE = "default-enrollment-invitation";
}
public static final class OperationAttributes {

@ -195,7 +195,6 @@ public class DeviceManagementPluginRepository implements DeviceManagerStartupLis
} else {
deviceTaskManagerService.startTask(deviceManagementService.getType(),
operationMonitoringTaskConfig);
// TODO: In here a race condition can arise. Need to handle it.
}
}
} catch (DeviceMgtTaskException e) {

@ -403,6 +403,7 @@ public class AnnotationProcessor {
.getMethod(SWAGGER_ANNOTATIONS_PROPERTIES_KEY), annotatedScopes[i], STRING));
permissions = (String[])methodHandler.invoke(annotatedScopes[i], scopeClass
.getMethod(SWAGGER_ANNOTATIONS_PROPERTIES_PERMISSIONS, null),null);
aggregatedPermissions.setLength(0);
for (String permission : permissions) {
aggregatedPermissions.append(permission);
aggregatedPermissions.append(" ");

@ -33,6 +33,7 @@ public class PolicyConfiguration {
private int minRetriesToMarkUnreachable;
private int minRetriesToMarkInactive;
private List<String> platforms;
private String policyEvaluationPoint;
@XmlElement(name = "MonitoringClass", required = true)
public String getMonitoringClass() {
@ -98,4 +99,13 @@ public class PolicyConfiguration {
this.platforms = platforms;
}
@XmlElement(name = "PolicyEvaluationPoint", required = true)
public String getPolicyEvaluationPointName() {
return policyEvaluationPoint;
}
public void setPolicyEvaluationPointName(String policyEvaluationPointName) {
this.policyEvaluationPoint = policyEvaluationPointName;
}
}

@ -76,12 +76,12 @@ public class DeviceTaskManagerServiceComponent {
}
}
private void getDeviceOperationMonitoringConfig(ComponentContext componentContext) throws DeviceMgtTaskException {
private void getDeviceOperationMonitoringConfig(ComponentContext componentContext)
throws DeviceMgtTaskException {
DeviceTaskManagerService deviceTaskManagerService = new DeviceTaskManagerServiceImpl();
DeviceManagementDataHolder.getInstance().setDeviceTaskManagerService(
deviceTaskManagerService);
DeviceManagementDataHolder.getInstance().setDeviceTaskManagerService(deviceTaskManagerService);
componentContext.getBundleContext().registerService(DeviceTaskManagerService.class,
deviceTaskManagerService, null);
@ -89,11 +89,10 @@ public class DeviceTaskManagerServiceComponent {
Map<String, OperationMonitoringTaskConfig> deviceConfigMap = DeviceMonitoringOperationDataHolder
.getInstance().getOperationMonitoringConfigFromMap();
for (String platformType : new ArrayList<String>(deviceConfigMap.keySet())) {
for (String platformType : new ArrayList<>(deviceConfigMap.keySet())) {
deviceTaskManagerService.startTask(platformType, deviceConfigMap.get(platformType));
deviceConfigMap.remove(platformType);
}
}
@SuppressWarnings("unused")

@ -81,7 +81,7 @@ public interface DeviceManagementProviderService {
*/
PaginationResult getAllDevices(PaginationRequest request) throws DeviceManagementException;
void sendEnrolmentInvitation(EmailMetaInfo metaInfo) throws DeviceManagementException;
void sendEnrolmentInvitation(String templateName, EmailMetaInfo metaInfo) throws DeviceManagementException;
void sendRegistrationEmail(EmailMetaInfo metaInfo) throws DeviceManagementException;

@ -50,6 +50,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.DeviceManagementPluginRepository;
import org.wso2.carbon.device.mgt.core.dao.ApplicationDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
@ -73,10 +74,12 @@ import org.wso2.carbon.user.api.UserStoreException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class DeviceManagementProviderServiceImpl implements DeviceManagementProviderService,
@ -752,21 +755,25 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
@Override
public void sendEnrolmentInvitation(EmailMetaInfo metaInfo) throws DeviceManagementException {
public void sendEnrolmentInvitation(String templateName, EmailMetaInfo metaInfo) throws DeviceManagementException {
Map<String, TypedValue<Class<?>, Object>> params = new HashMap<>();
params.put(org.wso2.carbon.device.mgt.core.DeviceManagementConstants.EmailAttributes.FIRST_NAME,
new TypedValue<Class<?>, Object>(String.class, metaInfo.getProperty("first-name")));
Properties props = metaInfo.getProperties();
Enumeration e = props.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
params.put(key, new TypedValue<Class<?>, Object>(String.class, props.getProperty(key)));
}
params.put(org.wso2.carbon.device.mgt.core.DeviceManagementConstants.EmailAttributes.SERVER_BASE_URL_HTTPS,
new TypedValue<Class<?>, Object>(String.class, DeviceManagerUtil.getServerBaseHttpsUrl()));
params.put(org.wso2.carbon.device.mgt.core.DeviceManagementConstants.EmailAttributes.SERVER_BASE_URL_HTTP,
new TypedValue<Class<?>, Object>(String.class, DeviceManagerUtil.getServerBaseHttpUrl()));
try {
EmailContext ctx =
new EmailContext.EmailContextBuilder(new ContentProviderInfo("user-enrollment", params),
new EmailContext.EmailContextBuilder(new ContentProviderInfo(templateName, params),
metaInfo.getRecipients()).build();
DeviceManagementDataHolder.getInstance().getEmailSenderService().sendEmail(ctx);
} catch (EmailSendingFailedException e) {
throw new DeviceManagementException("Error occurred while sending enrollment invitation", e);
} catch (EmailSendingFailedException ex) {
throw new DeviceManagementException("Error occurred while sending enrollment invitation", ex);
}
}
@ -787,7 +794,10 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
new TypedValue<Class<?>, Object>(String.class, DeviceManagerUtil.getServerBaseHttpUrl()));
try {
EmailContext ctx =
new EmailContext.EmailContextBuilder(new ContentProviderInfo("user-registration", params),
new EmailContext.EmailContextBuilder(
new ContentProviderInfo(
DeviceManagementConstants.EmailAttributes.USER_REGISTRATION_TEMPLATE,
params),
metaInfo.getRecipients()).build();
DeviceManagementDataHolder.getInstance().getEmailSenderService().sendEmail(ctx);
} catch (EmailSendingFailedException e) {
@ -1222,17 +1232,9 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
@Override
public List<MonitoringOperation> getMonitoringOperationList(String deviceType) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
// Map<DeviceTypeIdentifier, DeviceManagementService> deviceManagementServiceMap =
// pluginRepository.getAllDeviceManagementServices(tenantId);
DeviceManagementService dms = pluginRepository.getDeviceManagementService(deviceType, tenantId);
// ;
// OperationMonitoringTaskConfig operationMonitoringTaskConfig;
//Map<String, List<MonitoringOperation>> deviceTypeSpecificMonitoringOperations = new HashMap<>();
// for(DeviceTypeIdentifier dti : deviceManagementServiceMap.keySet()){
// dms = deviceManagementServiceMap.get(dti);
//
// }
OperationMonitoringTaskConfig operationMonitoringTaskConfig = dms.getOperationMonitoringConfig();
return operationMonitoringTaskConfig.getMonitoringOperation();
}

@ -19,8 +19,10 @@
package org.wso2.carbon.device.mgt.core.task.impl;
import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException;
import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager;
import org.wso2.carbon.ntask.core.Task;
@ -32,10 +34,18 @@ public class DeviceDetailsRetrieverTask implements Task {
private static Log log = LogFactory.getLog(DeviceDetailsRetrieverTask.class);
// private DeviceTaskManager deviceTaskManager = new DeviceTaskManagerImpl();
private String deviceType;
private String oppConfig;
private OperationMonitoringTaskConfig operationMonitoringTaskConfig;
@Override
public void setProperties(Map<String, String> map) {
deviceType = map.get("DEVICE_TYPE");
oppConfig = map.get("OPPCONFIG");
Gson gson = new Gson();
operationMonitoringTaskConfig = gson.fromJson(oppConfig,
OperationMonitoringTaskConfig.class);
}
@Override
@ -49,14 +59,18 @@ public class DeviceDetailsRetrieverTask implements Task {
log.debug("Device details retrieving task started to run.");
}
DeviceTaskManager deviceTaskManager = new DeviceTaskManagerImpl(deviceType);
DeviceTaskManager deviceTaskManager = new DeviceTaskManagerImpl(deviceType,
operationMonitoringTaskConfig);
//pass the configurations also from here, monitoring tasks
try {
deviceTaskManager.addOperations();
} catch (DeviceMgtTaskException e) {
log.error("Error occurred while trying to add the operations to device to retrieve device details.", e);
log.error(
"Error occurred while trying to add the operations to device to retrieve device details.",
e);
}
}
}

@ -25,6 +25,7 @@ import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
@ -46,30 +47,26 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
private static Log log = LogFactory.getLog(DeviceTaskManagerImpl.class);
private String deviceType;
private static Map<Integer, Map<String, Long>> map = new HashMap<>();
private OperationMonitoringTaskConfig operationMonitoringTaskConfig;
public DeviceTaskManagerImpl(String deviceType,
OperationMonitoringTaskConfig operationMonitoringTaskConfig) {
this.operationMonitoringTaskConfig = operationMonitoringTaskConfig;
this.deviceType = deviceType;
}
public DeviceTaskManagerImpl(String deviceType) {
this.deviceType = deviceType;
}
//get device type specific operations
public List<MonitoringOperation> getOperationList() throws DeviceMgtTaskException {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder
.getInstance().
getDeviceManagementProvider();
return deviceManagementProviderService.getMonitoringOperationList(
deviceType);//Get task list from each device type
private List<MonitoringOperation> getOperationList() throws DeviceMgtTaskException {
return operationMonitoringTaskConfig.getMonitoringOperation();
}
@Override
public int getTaskFrequency() throws DeviceMgtTaskException {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder
.getInstance().
getDeviceManagementProvider();
return deviceManagementProviderService.getDeviceMonitoringFrequency(deviceType);
return operationMonitoringTaskConfig.getFrequency();
}
// @Override
@ -80,11 +77,7 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
@Override
public boolean isTaskEnabled() throws DeviceMgtTaskException {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder
.getInstance().
getDeviceManagementProvider();
return deviceManagementProviderService.isDeviceMonitoringEnabled(deviceType);
return operationMonitoringTaskConfig.isEnabled();
}
@ -149,13 +142,22 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
return opNames;
}
private List<MonitoringOperation> getOperationListforTask() throws DeviceMgtTaskException {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder
.getInstance().
getDeviceManagementProvider();
return deviceManagementProviderService.getMonitoringOperationList(
deviceType);//Get task list from each device type
}
@Override
public boolean isTaskOperation(String opName) {
try {
List<MonitoringOperation> monitoringOperations = this.getOperationList();
List<MonitoringOperation> monitoringOperations = this.getOperationListforTask();
for (MonitoringOperation taop : monitoringOperations) {
if (taop.getTaskName().equalsIgnoreCase(opName)) {
return true;

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.core.task.impl;
import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -46,9 +47,8 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
private static Log log = LogFactory.getLog(DeviceTaskManagerServiceImpl.class);
@Override
public void startTask(String deviceType, OperationMonitoringTaskConfig operationMonitoringTaskConfig) throws DeviceMgtTaskException {
// String TASK_NAME = deviceType;
public void startTask(String deviceType, OperationMonitoringTaskConfig operationMonitoringTaskConfig)
throws DeviceMgtTaskException {
log.info("Task adding for " + deviceType);
@ -62,7 +62,8 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
log.debug("Device details retrieving task is started for the tenant id " + tenantId);
// log.debug("Device details retrieving task is at frequency of : " + deviceTaskManager
// .getTaskFrequency());
log.debug("Device details retrieving task is at frequency of : " + operationMonitoringTaskConfig
log.debug(
"Device details retrieving task is at frequency of : " + operationMonitoringTaskConfig
.getFrequency());
}
@ -73,32 +74,38 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
triggerInfo.setIntervalMillis(operationMonitoringTaskConfig.getFrequency());
triggerInfo.setRepeatCount(-1);
Gson gson = new Gson();
String operationConfigs = gson.toJson(operationMonitoringTaskConfig);
Map<String, String> properties = new HashMap<>();
properties.put(TENANT_ID, String.valueOf(tenantId));
properties.put("DEVICE_TYPE", deviceType);
properties.put("OPPCONFIG", operationConfigs);
String taskName = deviceType + String.valueOf(tenantId);
if (!taskManager.isTaskScheduled(deviceType)) {
TaskInfo taskInfo = new TaskInfo(deviceType, TASK_CLASS, properties, triggerInfo);
TaskInfo taskInfo = new TaskInfo(taskName, TASK_CLASS, properties, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
throw new DeviceMgtTaskException("Device details retrieving task is already started for this tenant " +
tenantId);
throw new DeviceMgtTaskException(
"Device details retrieving task is already started for this tenant " + tenantId);
}
} catch (TaskException e) {
throw new DeviceMgtTaskException("Error occurred while creating the task for tenant " + tenantId, e);
throw new DeviceMgtTaskException("Error occurred while creating the task for tenant " + tenantId,
e);
}
}
@Override
public void stopTask(String deviceType, OperationMonitoringTaskConfig operationMonitoringTaskConfig) throws DeviceMgtTaskException {
// String TASK_NAME = deviceType;
public void stopTask(String deviceType, OperationMonitoringTaskConfig operationMonitoringTaskConfig)
throws DeviceMgtTaskException {
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
@ -108,15 +115,15 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
}
} catch (TaskException e) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
throw new DeviceMgtTaskException("Error occurred while deleting the task for tenant " + tenantId, e);
throw new DeviceMgtTaskException("Error occurred while deleting the task for tenant " + tenantId,
e);
}
}
@Override
public void updateTask(String deviceType, OperationMonitoringTaskConfig operationMonitoringTaskConfig) throws DeviceMgtTaskException {
// String TASK_NAME = deviceType;
public void updateTask(String deviceType, OperationMonitoringTaskConfig operationMonitoringTaskConfig)
throws DeviceMgtTaskException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
// deviceTaskManager = new DeviceTaskManagerImpl();
@ -134,21 +141,20 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
Map<String, String> properties = new HashMap<>();
properties.put(TENANT_ID, String.valueOf(tenantId));
TaskInfo taskInfo = new TaskInfo(deviceType, TASK_CLASS, properties,
triggerInfo);
TaskInfo taskInfo = new TaskInfo(deviceType, TASK_CLASS, properties, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
throw new DeviceMgtTaskException("Device details retrieving task has not been started for this tenant " +
throw new DeviceMgtTaskException(
"Device details retrieving task has not been started for this tenant " +
tenantId + ". Please start the task first.");
}
} catch (TaskException e) {
throw new DeviceMgtTaskException("Error occurred while updating the task for tenant " + tenantId, e);
throw new DeviceMgtTaskException("Error occurred while updating the task for tenant " + tenantId,
e);
}
}
}

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -233,17 +233,7 @@
<div class="modal-content">
<div class="row">
<div class="col-md-3 col-centered">
<h3>Device was successfully associated with group.</h3>
</div>
</div>
</div>
</div>
<div id="group-deassociate-device-200-content" class="hide">
<div class="modal-content">
<div class="row">
<div class="col-md-3 col-centered">
<h3>Device was successfully removed from group.</h3>
<h3>Device associations updated.</h3>
</div>
</div>
</div>

@ -258,8 +258,10 @@ function loadDevices(searchType, searchParam) {
data: 'name',
class: 'remove-padding icon-only content-fill',
render: function (data, type, row, meta) {
return '<div class="thumbnail icon"><img class="square-element text fw " src="' + getDeviceTypeThumb(
row.deviceType) + '"/></div>';
return '<a href="' + context + '/device/' + row.deviceType + '?id=' + row.deviceIdentifier
+ '"><div class="thumbnail icon"><img class="square-element text fw " src="'
+ getDeviceTypeThumb(
row.deviceType) + '"/></div></a>';
}
},
{
@ -333,21 +335,13 @@ function loadDevices(searchType, searchParam) {
var deviceIdentifier = row.deviceIdentifier;
var html = '<span></span>';
if (status != 'REMOVED') {
html =
'<a href="device/' + deviceType + '?id=' + deviceIdentifier + '" data-click-event="remove-form"'
+
' class="btn padding-reduce-on-grid-view"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i>'
+
'<i class="fw fw-view fw-stack-1x"></i></span><span class="hidden-xs hidden-on-grid-view">View</span></a>';
html = '';
if (analyticsEnabled(row.deviceType)) {
html +=
'<a href="device/' + deviceType + '/analytics?deviceId=' + deviceIdentifier + '&deviceName='
+ row.name + '" ' +
'data-click-event="remove-form" class="btn padding-reduce-on-grid-view"><span class="fw-stack">'
+
'<i class="fw fw-ring fw-stack-2x"></i><i class="fw fw-statistics fw-stack-1x"></i></span>'
+
html += '<a href="' + context + '/device/' + deviceType + '/analytics?deviceId=' +
deviceIdentifier + '&deviceName=' + row.name + '" ' + 'data-click-event="remove-form"' +
' class="btn padding-reduce-on-grid-view"><span class="fw-stack">' +
'<i class="fw fw-ring fw-stack-2x"></i><i class="fw fw-statistics fw-stack-1x"></i></span>' +
'<span class="hidden-xs hidden-on-grid-view">Analytics</span>';
}
@ -562,6 +556,34 @@ function hidePopup() {
$('.modal-backdrop').remove();
}
function markAlreadyAssignedGroups(deviceId, deviceType) {
var successCallback = function (data, textStatus, xhr) {
data = JSON.parse(data);
if (xhr.status == 200) {
if (data.length > 0) {
for (var i = 0; i < data.length; i++) {
$('.groupCheckBoxes').each(
function () {
if (data[i].id == $(this).data('groupid')) {
$(this).attr('checked', true);
}
}
);
}
} else {
return;
}
} else {
displayErrors(xhr);
}
};
invokerUtil.get("/api/device-mgt/v1.0/groups/device?deviceId=" + deviceId + "&deviceType=" + deviceType,
successCallback, function (message) {
displayErrors(message);
});
}
/**
* Following functions should be triggered after AJAX request is made.
*/
@ -584,27 +606,42 @@ function attachDeviceEvents() {
var serviceURL;
if ($.hasPermission("LIST_ALL_GROUPS")) {
serviceURL = "/api/device-mgt/v1.0/groups";
serviceURL = "/api/device-mgt/v1.0/admin/groups?limit=100";
} else if ($.hasPermission("LIST_GROUPS")) {
//Get authenticated users groups
serviceURL = "/api/device-mgt/v1.0/groups/user/" + currentUser + "/all";
serviceURL = "/api/device-mgt/v1.0/groups?limit=100";
}
invokerUtil.get(serviceURL, function (data) {
var groups = JSON.parse(data);
var str = '<br /><select id="assign-group-selector" style="color:#3f3f3f;padding:5px;width:250px;">';
var html = '<br />';
for (var i = 0; i < groups.deviceGroups.length; i++) {
str += '<option value="' + groups.deviceGroups[i].id + '">' +
groups.deviceGroups[i].name + '</option>';
if (groups.deviceGroups[i].owner != "wso2.system.user") {
html += '<div class="wr-input-control"><label class="wr-input-control checkbox">' +
'<input class="groupCheckBoxes" type="checkbox" data-groupid="' + groups.deviceGroups[i].id + '" />' +
'<span class="helper" title="' + groups.deviceGroups[i].name + '">' + groups.deviceGroups[i].name +
'</span></label></div>';
}
str += '</select>';
$('#user-groups').html(str);
}
$('#user-groups').html(html);
markAlreadyAssignedGroups(deviceId, deviceType);
$("a#group-device-yes-link").show();
$("a#group-device-yes-link").click(function () {
var selectedGroup = $('#assign-group-selector').val();
serviceURL = "/api/device-mgt/v1.0/groups/id/" + selectedGroup + "/devices/add";
var deviceIdentifiers = [{"id": deviceId, "type": deviceType}];
invokerUtil.post(serviceURL, deviceIdentifiers, function (data) {
var deviceIdentifier = {"id": deviceId, "type": deviceType};
var deviceGroupIds = [];
$('.modal .groupCheckBoxes').each(
function () {
if ($(this).is(':checked')) {
deviceGroupIds.push($(this).data('groupid'));
}
}
);
var deviceToGroupsAssignment = {
deviceIdentifier: deviceIdentifier,
deviceGroupIds: deviceGroupIds
};
serviceURL = "/api/device-mgt/v1.0/groups/device/assign";
invokerUtil.post(serviceURL, deviceToGroupsAssignment, function (data) {
$(modalPopupContent).html($('#group-associate-device-200-content').html());
setTimeout(function () {
hidePopup();

@ -0,0 +1,43 @@
{{!
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.
}}
{{unit "cdmf.unit.ui.title" pageTitle="Policy Management | View Policy"}}
{{#zone "breadcrumbs"}}
<li>
<a href="{{@app.context}}/">
<i class="icon fw fw-home"></i>
</a>
</li>
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policies">
Policies
</a>
</li>
<li>
<a href="#">
View
</a>
</li>
{{/zone}}
{{#zone "content"}}
{{unit "cdmf.unit.device.operation-mod"}}
{{unit "cdmf.unit.effective-policy.view"}}
{{/zone}}

@ -0,0 +1,24 @@
/*
* 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.
*/
function onRequest(context) {
var utility = require("/app/modules/utility.js")["utility"];
var deviceType = context.uriParams.deviceType;
var deviceId = context.uriParams.deviceId;
return {"deviceTypePolicyView": utility.getTenantedDeviceUnitName(deviceType, deviceId,"policy-view")};
}

@ -0,0 +1,5 @@
{
"version": "1.0.0",
"uri": "/policy/effective-policy/",
"layout": "cdmf.layout.default"
}

@ -118,16 +118,16 @@
</div>
<div id="user-names">
<h4>
Select user roles to manage group sharing
Select user role(s)
<br><br>
<div style="max-height: 200px; overflow: scroll" id="rolesListing">
<div style="max-height: 200px; overflow: auto" id="rolesListing">
</div>
</h4>
</div>
</div>
<div class="modal-footer">
<div class="buttons">
{{#if permissions.CREATE_GROUP_ROLES}}
{{#if permissions.ADD_ROLE}}
<a href="{{@app.context}}/role/add" class="btn-operations">
New Role
</a>
@ -186,9 +186,9 @@
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Group was successfully updated.</h3>
<h3>Group successfully updated.</h3>
<br />
Do you need to Add / Remove users to the chosen roles?
Do you want to manage users?
<div class="buttons">
<a href="{{@app.context}}/users" id="share-group-add-users-yes-link"
class="btn-operations">
@ -211,7 +211,7 @@
<div class="col-lg-5 col-md-6 col-centered">
<h3>New Role was successfully created.</h3>
<br />
Do you need to Add / Remove users to the chosen roles?
Do you need to Add / Remove users from the chosen roles?
<div class="buttons">
<a href="{{@app.context}}/users" id="share-group-add-users-yes-link"
class="btn-operations">

@ -20,13 +20,11 @@ function onRequest(context) {
var groupModule = require("/app/modules/business-controllers/group.js")["groupModule"];
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var constants = require("/app/modules/constants.js");
var groupPermissions = require("/app/pages/cdmf.page.groups/public/group-permissions.json");
var currentUser = session.get(constants.USER_SESSION_KEY);
var page = {};
if (currentUser) {
page.permissions = userModule.getUIPermissions();
page.permissions.list = stringify(page.permissions);
page.groupPermissions = groupPermissions.permissionList;
page.currentUser = currentUser;
var groupCount = groupModule.getGroupCount();
if (groupCount > 0) {

@ -1,15 +0,0 @@
{
"permissionList":["device-mgt/admin/groups/view",
"device-mgt/groups/add",
"device-mgt/groups/devices/add",
"device-mgt/groups/devices/remove",
"device-mgt/groups/devices/view",
"device-mgt/groups/remove",
"device-mgt/groups/roles/create",
"device-mgt/groups/roles/view",
"device-mgt/groups/share",
"device-mgt/groups/update",
"device-mgt/groups/users/view",
"device-mgt/groups/view"
]
}

@ -96,7 +96,7 @@ function loadGroups() {
serviceURL = "/api/device-mgt/v1.0/admin/groups";
} else if ($.hasPermission("LIST_GROUPS")) {
//Get authenticated users groups
serviceURL = "/api/device-mgt/v1.0/groups/user/" + currentUser;
serviceURL = "/api/device-mgt/v1.0/groups";
} else {
$("#loading-content").remove();
$('#device-table').addClass('hidden');

@ -0,0 +1,53 @@
{{!
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.
}}
{{unit "cdmf.unit.ui.modal"}}
{{#zone "content"}}
<div id="invite-by-email-modal" class="hidden">
<div id="invite-by-email-body" class="panel panel-default">
<div class="panel-body">
<div id="user-create-form" class="col-centered col-lg-8 wr-content">
<div class="text-left">
<div class="wr-input-control">
<select multiple="true" name="choose_usr_email[]" id="choose_usr_email"
class="form-control">
</select>
</div>
</div>
</div>
<p>Please add one or more email addresses separated by a <b>comma ( , )</b> to send an email invitation
which includes</br>
instructions on how to download the respective device agent.</p>
</div>
</div>
</div>
{{/zone}}
{{#zone "topCss"}}
{{css "css/invite-modal-styles.css"}}
{{/zone}}
{{#zone "topJs"}}
<script type="text/javascript"> var deviceTypeView = "{{@unit.params.deviceTypeView}}"; </script>
{{/zone}}
{{#zone "bottomJs"}}
{{js "js/invite-modal.js"}}
{{/zone}}

@ -0,0 +1,86 @@
/**
* Created by imesh on 16/12/16.
*/
/**
* Opens a modal popup with input to enter multiple email addresses to send invites
*/
function toggleEmailInvite(){
modalDialog.header('<h4 class="pull-left modal-title"><span class="fw-stack add-margin-right-1x">' +
'<i class="fw fw-user fw-stack-2x"></i>' +
'<span class="fw-stack fw-move-right fw-move-bottom">' +
'<i class="fw fw-ring fw-stack-2x"></i>' +
'<i class="fw fw-circle fw-stack-2x fw-stroke text-info"></i>' +
'<i class="fw fw-add fw-stack-1x fw-inverse"></i></span></span>Send Invites</h4>');
modalDialog.content($("#invite-by-email-body").html());
modalDialog.footer('<div class="buttons">' +
'<a href="javascript:sendInvites()" class="btn-operations btn-default">Send Invite(s)</a>' +
'</div>');
modalDialog.show();
//$('.modal-content .select2-container').remove();
$('.modal-content #choose_usr_email').select2({
tags: true,
tokenSeparators: [",", " "],
createTag: function(term, data) {
var value = term.term;
if(validateEmail(value)) {
return {
id: value,
text: value
};
}
return null;
}
});
}
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
/**
* Action to get email object from select2 element
* @returns {boolean}
*/
function sendInvites(){
var emailObj = $('.modal-content #choose_usr_email').select2('data'),
emailArr = [];
if(emailObj.length <= 0){
console.log('no values to print');
return false;
}
emailObj.forEach(function(el){
emailArr.push(el.text);
});
var deviceEmailObj = {
"deviceType" : deviceTypeView,
"recipients": emailArr
};
invokerUtil.post(
"/api/device-mgt/v1.0/users/enrollment-invite",
deviceEmailObj,
function () {
modalDialog.header("Invitations sent");
modalDialog.content("<h4>Invitation email for enrollment was successfully sent.</h4>");
modalDialog.footer('<div class="buttons"> <a href="#" id="invite-user-success-link" ' +
'class="btn-operations">Ok </a> </div>');
$("a#invite-user-success-link").click(function () {
modalDialog.hide();
});
},
function () {
modalDialog.header('<span class="fw-stack"> <i class="fw fw-ring fw-stack-2x"></i> <i class="fw ' +
'fw-error fw-stack-1x"></i> </span> Unexpected Error !');
modalDialog.content('An unexpected error occurred. Try again later.');
modalDialog.footer('<div class="buttons"> <a href="#" id="invite-user-error-link" ' +
'class="btn-operations">Ok </a> </div>');
$("a#invite-user-error-link").click(function () {
modalDialog.hide();
});
}
);
}

@ -0,0 +1,10 @@
{{unit "cdmf.unit.lib.codemirror"}}
<div class="wr-input-control">
<div class="cus-col-100">
<textarea id="policy-definition-input" placeholder="Enter the policy"></textarea>
</div>
<br class="c-both"/>
</div>
{{#zone "bottomJs"}}
{{js "js/policy-edit.js"}}
{{/zone}}

@ -0,0 +1,60 @@
/*
* 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.
*/
window.queryEditor = CodeMirror.fromTextArea(document.getElementById('policy-definition-input'), {
mode: "application/json",
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true
});
var validatePolicyProfile = function () {
return true;
};
/**
* Generates policy profile feature list which will be saved with the profile.
*
* This function will be invoked from the relevant cdmf unit at the time of policy creation.
*
* @returns {Array} profile payloads
*/
var generateGenericPayload = function () {
return [{
"featureCode": "CONFIG",
"deviceType": policy["platform"],
"content": {"policyDefinition": window.queryEditor.getValue()}
}];
};
/**
* Populates policy configuration to the ui elements.
*
* This method will be invoked from the relevant cdmf unit when the edit page gets loaded.
*
* @param profileFeatureList saved feature list
*/
var populateGenericProfileOperations = function (profileFeatureList) {
var content = JSON.parse(profileFeatureList[0]["content"]);
window.queryEditor.setValue(content.policyDefinition);
setTimeout(function() {
window.queryEditor.refresh();
}, 100);
};

@ -0,0 +1,10 @@
{{unit "cdmf.unit.lib.codemirror"}}
<div class="wr-input-control">
<div class="cus-col-100">
<textarea id="policy-definition-input" placeholder="Enter the policy"></textarea>
</div>
<br class="c-both"/>
</div>
{{#zone "bottomJs"}}
{{js "js/policy-view.js"}}
{{/zone}}

@ -0,0 +1,42 @@
/*
* 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.
*/
window.queryEditor = CodeMirror.fromTextArea(document.getElementById('policy-definition-input'), {
mode: "application/json",
indentWithTabs: true,
smartIndent: true,
readOnly: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true
});
/**
* Populates policy configuration to the ui elements.
*
* This method will be invoked from the relevant cdmf unit when the edit page gets loaded.
*
* @param profileFeatureList saved feature list
*/
var populateGenericProfileOperations = function (profileFeatureList) {
var content = JSON.parse(profileFeatureList[0]["content"]);
window.queryEditor.setValue(content.policyDefinition);
setTimeout(function() {
window.queryEditor.refresh();
}, 100);
};

@ -1,6 +1,4 @@
{{#zone "topCss"}}
{{css "css/codemirror.css"}}
{{/zone}}
{{unit "cdmf.unit.lib.codemirror"}}
<div class="wr-input-control">
<div class="cus-col-100">
<textarea id="policy-definition-input" placeholder="Enter the policy"></textarea>
@ -8,7 +6,5 @@
<br class="c-both"/>
</div>
{{#zone "bottomJs"}}
{{js "js/codemirror.js"}}
{{js "js/sql.js"}}
{{js "js/editor.js"}}
{{js "js/policy-wizard.js"}}
{{/zone}}

@ -17,21 +17,18 @@
*/
window.queryEditor = CodeMirror.fromTextArea(document.getElementById('policy-definition-input'), {
mode: MIME_TYPE_SIDDHI_QL,
mode: "application/json",
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true,
extraKeys: {
"Shift-2": function (cm) {
insertStr(cm, cm.getCursor(), '@');
CodeMirror.showHint(cm, getAnnotationHints);
},
"Ctrl-Space": "autocomplete"
}
autofocus: true
});
setTimeout(function() {
window.queryEditor.refresh();
}, 100);
var validatePolicyProfile = function () {
return true;
};
@ -46,7 +43,7 @@ var validatePolicyProfile = function () {
var generateGenericPayload = function () {
return [{
"featureCode": "CONFIG",
"deviceTypeId": policy["platformId"],
"deviceType": policy["platform"],
"content": {"policyDefinition": window.queryEditor.getValue()}
}];
};

@ -1,310 +0,0 @@
/*
* 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.
*/
/*Annotations, Annotation Names and relevant tokens*/
var ANNOTATION_IMPORT = "Import";
var ANNOTATION_EXPORT = "Export";
var ANNOTATION_TOKEN_AT = "@";
var ANNOTATION_TOKEN_OPENING_BRACKET = "(";
var ANNOTATION_TOKEN_CLOSING_BRACKET = ")";
var REGEX_LINE_STARTING_WITH_PLAN = /^@Plan.*/g;
var REGEX_LINE_STARTING_WITH_SINGLE_LINE_COMMENT = /^--.*/g;
var REGEX_LINE_STARTING_WITH_MULTI_LINE_COMMENT = /^\/\*.*\*\//g;
var REGEX_LINE_STARTING_WITH_IMPORT_STATEMENT = /^@Import.*/g;
var SIDDHI_STATEMENT_DELIMETER = ";";
var SIDDHI_LINE_BREAK = "\n";
var SIDDHI_LINE_BREAK_CHARACTER = '\n';
var SIDDHI_SINGLE_QUOTE = "'";
var SIDDHI_SPACE_LITERAL = " ";
var SIDDHI_LITERAL_DEFINE_STREAM = "define stream";
var MIME_TYPE_SIDDHI_QL = "text/siddhi-ql";
CodeMirror.defineMode("sql", function (config, parserConfig) {
"use strict";
var client = parserConfig.client || {},
atoms = parserConfig.atoms || {"false":true, "true":true, "null":true},
builtin = parserConfig.builtin || {},
keywords = parserConfig.keywords || {},
operatorChars = parserConfig.operatorChars || /^[*+\-%<>!=&|~^]/,
support = parserConfig.support || {},
hooks = parserConfig.hooks || {},
dateSQL = parserConfig.dateSQL || {"date":true, "time":true, "timestamp":true};
function tokenBase(stream, state) {
var ch = stream.next();
// call hooks from the mime type
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
// numbers
// ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
stream.match(/^[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/);
support.decimallessFloat == true && stream.eat('.');
return "number";
} else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
// strings
// ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
state.tokenize = tokenLiteral(ch);
return state.tokenize(stream, state);
} else if (/^[\(\),\;\[\]]/.test(ch)) {
// no highlightning
return null;
} else if ((ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
// 1-line comments
// ref: https://kb.askmonty.org/en/comment-syntax/
stream.skipToEnd();
return "comment";
} else if (ch == "/" && stream.eat("*")) {
// multi-line comments
// ref: https://kb.askmonty.org/en/comment-syntax/
state.tokenize = tokenComment;
return state.tokenize(stream, state);
} else if (ch == ".") {
// .1 for 0.1
if (support.zerolessFloat == true && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i)) {
return "number";
}
} else {
stream.eatWhile(/^[_\-\w\d]/); /* Character '-' will also be eaten, to prevent the highlight happening in keywords being embedded in non-keyword strings. For example, 'all' in 'all-nonkeyword' */
var word = stream.current().toLowerCase(); // Added toLowerCase() to highlight keywords in a case insensitive manner.
// dates (standard SQL syntax)
// ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
return "number";
if (atoms.hasOwnProperty(word)) return "atom";
if (builtin.hasOwnProperty(word)) return "builtin";
if (keywords.hasOwnProperty(word)) return "keyword";
if (client.hasOwnProperty(word)) return "string-2";
return null;
}
}
// 'string', with char specified in quote escaped by '\'
function tokenLiteral(quote) {
return function (stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) {
state.tokenize = tokenBase;
break;
}
escaped = !escaped && ch == "\\";
}
return "string";
};
}
function tokenComment(stream, state) {
while (true) {
if (stream.skipTo("*")) {
stream.next();
if (stream.eat("/")) {
state.tokenize = tokenBase;
break;
}
} else {
stream.skipToEnd();
break;
}
}
return "comment";
}
function pushContext(stream, state, type) {
state.context = {
prev:state.context,
indent:stream.indentation(),
col:stream.column(),
type:type
};
}
function popContext(state) {
state.indent = state.context.indent;
state.context = state.context.prev;
}
return {
startState:function () {
return {tokenize:tokenBase, context:null};
},
token:function (stream, state) {
if (stream.sol()) {
if (state.context && state.context.align == null)
state.context.align = false;
}
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (style == "comment") return style;
if (state.context && state.context.align == null)
state.context.align = true;
var tok = stream.current();
if (tok == "(")
pushContext(stream, state, ")");
else if (tok == "[")
pushContext(stream, state, "]");
else if (state.context && state.context.type == tok)
popContext(state);
return style;
},
indent:function (state, textAfter) {
var cx = state.context;
if (!cx) return CodeMirror.Pass;
var closing = textAfter.charAt(0) == cx.type;
if (cx.align) return cx.col + (closing ? 0 : 1);
else return cx.indent + (closing ? 0 : config.indentUnit);
},
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "--"
};
});
(function () {
"use strict";
// `identifier`
function hookIdentifier(stream) {
// MySQL/MariaDB identifiers
// ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
var ch;
while ((ch = stream.next()) != null) {
if (ch == "`" && !stream.eat("`")) return "variable-2";
}
stream.backUp(stream.current().length - 1);
return stream.eatWhile(/\w/) ? "variable-2" : null;
}
// variable token
function hookVar(stream) {
// variables
// @@prefix.varName @varName
// varName can be quoted with ` or ' or "
// ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
if (stream.eat("@")) {
stream.match(/^session\./);
stream.match(/^local\./);
stream.match(/^global\./);
}
if (stream.eat("'")) {
stream.match(/^.*'/);
return "variable-2";
} else if (stream.eat('"')) {
stream.match(/^.*"/);
return "variable-2";
} else if (stream.eat("`")) {
stream.match(/^.*`/);
return "variable-2";
} else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
return "variable-2";
}
return null;
}
;
// short client keyword token
function hookClient(stream) {
// \N means NULL
// ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
if (stream.eat("N")) {
return "atom";
}
// \g, etc
// ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
}
// these keywords are used by all SQL dialects (however, a mode can still overwrite it)
var sqlKeywordsWithoutSymbols = "all and as begin by contains define delete end events " +
"every first for from full group having inner insert into join last " +
"left not of on or outer output partition raw return right select snapshot stream table ";
var sqlKeywords = ", : ? # ( ) " + sqlKeywordsWithoutSymbols;
var builtIn = "bool double float int long object string ";
var atoms = "false true null ";
var dateSQL = "days hours milliseconds minutes months seconds ";
var allSqlSuggestions = sqlKeywordsWithoutSymbols + builtIn + atoms + dateSQL;
// turn a space-separated list into an array
function set(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
// A generic SQL Mode. It's not a standard, it just try to support what is generally supported
CodeMirror.defineMIME(MIME_TYPE_SIDDHI_QL, {
name:"sql",
keywords:set(sqlKeywords),
builtin:set(builtIn),
atoms:set(atoms),
operatorChars:/^[*+%<>!=/]/,
dateSQL:set(dateSQL),
support:set("doubleQuote "),
allSqlSuggestions:set(allSqlSuggestions)
});
}());
/*
How Properties of Mime Types are used by SQL Mode
=================================================
keywords:
A list of keywords you want to be highlighted.
functions:
A list of function names you want to be highlighted.
builtin:
A list of builtin types you want to be highlighted (if you want types to be of class "builtin" instead of "keyword").
operatorChars:
All characters that must be handled as operators.
client:
Commands parsed and executed by the client (not the server).
support:
A list of supported syntaxes which are not common, but are supported by more than 1 DBMS.
* ODBCdotTable: .tableName
* zerolessFloat: .1
* doubleQuote
* nCharCast: N'string'
* charsetCast: _utf8'string'
* commentHash: use # char for comments
* commentSlashSlash: use // for comments
* commentSpaceRequired: require a space after -- for comments
atoms:
Keywords that must be highlighted as atoms,. Some DBMS's support more atoms than others:
UNKNOWN, INFINITY, UNDERFLOW, NaN...
dateSQL:
Used for date/time SQL standard syntax, because not all DBMS's support same temporal types.
*/

@ -0,0 +1,64 @@
{{!
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.
}}
{{#zone "content"}}
<div id="qr-code-modal" data-enrollment-url="{{@unit.params.enrollmentURL}}" class="hidden">
<div class="modal-header">
<h4 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-mobile fw-stack-2x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-circle fw-stack-2x fw-stroke text-info"></i>
<i class="fw fw-add fw-stack-1x fw-inverse"></i>
</span>
</span>
Add your {{@unit.params.deviceTypeName}} device to {{@app.conf.appName}}
</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<hr>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<div class="panel-body col-centered text-center">
<h5>
Please scan the following QR code using your {{@unit.params.deviceTypeName}} device.
</h5>
<br>
<div class="panel panel-default">
<div class="panel-body">
<div class="qr-code"></div>
</div>
</div>
<br>
<h5>
Not having a QR code scanner in your device?
<br><br>
Try following link
<br><br>
<a href="{{@unit.params.enrollmentURL}}" target="_blank"><b>{{@unit.params.enrollmentURL}}</b></a>
<br><br>
on your device's Internet browser instead.
</h5>
</div>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations btn-default">Ok</a>
</div>
</div>
</div>
{{/zone}}

@ -16,12 +16,12 @@
under the License.
}}
{{#if virtualDeviceTypesList}}
<div class="row wr-device-board">
<div class="col-lg-12 wr-secondary-bar">
<span class="page-sub-title">Device Types</span>
</div>
</div>
<span id="device-listing-status-msg"></span>
<div class="container-fluid">
<table class="table table-striped table-hover list-table no-operations display responsive nowrap data-table grid-view no-toolbar"
id="device-type-grid">
@ -36,6 +36,24 @@
</tbody>
</table>
</div>
{{else}}
<div class="ast-container list-view">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h3 class="text-muted">
<i class="fw fw-mobile fw-3x"></i>
</h3>
<h3 class="text-muted">No device type is available to be displayed.</h3>
<a href="https://docs.wso2.com/display/IoTS100/Quick+Start+Guide" target="_blank"
class="btn-operations btn-default">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-document fw-stack-1x"></i>
</span>
Quick Startup Guide
</a>
</div>
</div>
{{/if}}
<br class="c-both"/>
{{#if virtualDeviceTypesList}}

@ -29,6 +29,9 @@ function onRequest(context) {
if (typesListResponse["status"] == "success") {
var deviceTypes = typesListResponse.content.deviceTypes;
if (deviceTypes) {
if (deviceTypes.length > 0){
viewModel.hasDeviceTypes = true;
}
var deviceTypesList = [], virtualDeviceTypesList = [];
for (var i = 0; i < deviceTypes.length; i++) {
var deviceType = deviceTypes[i];

@ -142,13 +142,6 @@ function loadDevices(searchType, searchParam){
}
} else {
$('#device-type-grid').addClass('hidden');
$('#device-listing-status-msg').html(
'<div class="col-centered text-center"><h3 class="text-muted"><i class="fw fw-mobile fw-3x"></i>' +
'</h3><h3 class="text-muted">No device type is available to be displayed.</h3>' +
'<a href="https://docs.wso2.com/display/IoTS100/Quick+Start+Guide" target="_blank" ' +
'class="btn-operations btn-default"><span class="fw-stack">' +
'<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-document fw-stack-1x"></i></span>' +
'Quick Startup Guide</a></div>');
}
$(".icon .text").res_text(0.2);

@ -16,7 +16,6 @@
* under the License.
*/
(function () {
var deviceId = $(".device-id");
var deviceIdentifier = deviceId.data("deviceid");
var deviceType = deviceId.data("type");
@ -49,6 +48,7 @@
function loadOperationsLog(update) {
var operationsLogTable = "#operations-log-table";
if (update) {
operationTable = $(operationsLogTable).DataTable();
$("#operations-spinner").removeClass("hidden");
@ -163,6 +163,8 @@
var viewModel = {};
viewModel["policy"] = activePolicy;
viewModel["deviceType"] = deviceType;
viewModel["deviceId"] = deviceId;
viewModel["appContext"] = context;
data = JSON.parse(data);
var content;
if (data["complianceData"]) {
@ -206,5 +208,3 @@
}
);
}
}());

@ -37,7 +37,7 @@
</div>
<div class="col-lg-3">
<span class="list-group-item-actions">
<a href="/policy/view?id={{policy.id}}"
<a href="{{appContext}}/policy/effective-policy?type={{deviceType}}&id={{deviceId}}"
class="cu-btn-inner policy-view-link" data-id="{{id}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>

@ -0,0 +1,152 @@
/*
* 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 policy = {};
var displayPolicy = function (policyPayloadObj) {
policy["name"] = policyPayloadObj["policyName"];
policy["platform"] = policyPayloadObj["profile"]["deviceType"];
// updating next-page wizard title with selected platform
$("#policy-heading").text(policy["platform"].toUpperCase() + " POLICY - " + policy["name"].toUpperCase());
$("#policy-platform").text(policy["platform"].toUpperCase());
$("#policy-assignment").text(policyPayloadObj.deviceGroups);
$("#policy-action").text(policyPayloadObj.compliance.toUpperCase());
$("#policy-description").text(policyPayloadObj["description"]);
var policyStatus = "Active";
if (policyPayloadObj["active"] == true && policyPayloadObj["updated"] == true) {
policyStatus = '<i class="fw fw-warning icon-success"></i> Active/Updated</span>';
} else if (policyPayloadObj["active"] == true && policyPayloadObj["updated"] == false) {
policyStatus = '<i class="fw fw-ok icon-success"></i> Active</span>';
} else if (policyPayloadObj["active"] == false && policyPayloadObj["updated"] == true) {
policyStatus = '<i class="fw fw-warning icon-warning"></i> Inactive/Updated</span>';
} else if (policyPayloadObj["active"] == false && policyPayloadObj["updated"] == false) {
policyStatus = '<i class="fw fw-error icon-danger"></i> Inactive</span>';
}
$("#policy-status").html(policyStatus);
if (policyPayloadObj.users == null) {
$("#policy-users").text("NONE");
}
else if (policyPayloadObj.users.length > 0) {
$("#policy-users").text(policyPayloadObj.users.toString().split(",").join(", "));
} else {
$("#users-row").addClass("hidden");
}
if (policyPayloadObj.deviceGroups == null) {
$("#policy-groups").text("NONE");
} else if (policyPayloadObj.deviceGroups.length > 0) {
debugger;
var deviceGroups = policyPayloadObj.deviceGroups;
var assignedGroups = [];
for (var index in deviceGroups) {
if (deviceGroups.hasOwnProperty(index)) {
assignedGroups.push(deviceGroups[index].name);
}
}
$("#policy-groups").text(assignedGroups.toString().split(",").join(", "));
} else {
$("#policy-groups").text("NONE");
}
if (policyPayloadObj.roles == null) {
$("#policy-roles").text("NONE");
}
else if (policyPayloadObj.roles.length > 0) {
$("#policy-roles").text(policyPayloadObj.roles.toString().split(",").join(", "));
} else {
$("#roles-row").addClass("hidden");
}
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-view/templates/' + deviceType + '-policy-view.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-view/js/' + deviceType + '-policy-view.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-view/css/' + deviceType + '-policy-view.css';
var policyOperationsTemplateCacheKey = deviceType + '-policy-operations';
$.isResourceExists(policyOperationsTemplateSrc, function (status) {
if (status) {
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) {
var content = template();
$("#device-type-policy-operations").html(content).removeClass("hidden");
$(".policy-platform").addClass("hidden");
$.isResourceExists(policyOperationsScriptSrc, function (status) {
if (status) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = policyOperationsScriptSrc;
$(".wr-advance-operations").prepend(script);
/*
This method should be implemented in the relevant plugin side and should include the logic to
populate the policy profile in the plugin specific UI.
*/
polulateProfileOperations(policyPayloadObj["profile"]["profileFeaturesList"]);
}
});
});
$.isResourceExists(policyOperationsStylesSrc, function (status) {
if (status) {
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = policyOperationsStylesSrc;
$(".wr-advance-operations").prepend(style);
}
});
} else {
$("#generic-policy-operations").removeClass("hidden");
}
$(".wr-advance-operations-init").addClass("hidden");
});
};
/**
* This method will return query parameter value given its name.
* @param name Query parameter name
* @returns {string} Query parameter value
*/
var getParameterByName = function (name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
};
$(document).ready(function () {
var policyPayloadObj;
// Adding initial state of wizard-steps.
invokerUtil.get(
"/api/device-mgt/v1.0" + "/policies/effective-policy/" + getParameterByName("type") + "/" + getParameterByName("id"),
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
policyPayloadObj = JSON.parse(data);
displayPolicy(policyPayloadObj);
}
},
// on error
function (jqXHR) {
console.log(jqXHR);
// should be redirected to an error page
}
);
});

@ -0,0 +1,83 @@
{{#zone "content"}}
{{!--#if isAuthorized--}}
{{#defineZone "policy-profile-top"}}
<div class="row wr-device-board">
<div class="col-lg-12 wr-secondary-bar">
<label id="policy-heading" class="device-id device-select">
</label>
</div>
</div>
{{/defineZone}}
<!-- #page-content-wrapper -->
<div class="page-content-wrapper">
<div class="row no-gutter add-padding-5x add-margin-top-5x" style="border: 1px solid #e4e4e4;">
<div class="media">
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Policy Overview
</div>
{{#defineZone "policy-detail-properties"}}
<table class="table table-responsive table-striped" id="members">
<tbody>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 14%;">Platform</td>
<td id="policy-platform" style="padding:10px 15px;"></td>
</tr>
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">Groups</td>
<td id="policy-groups" style="padding:10px 15px;"></td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Action upon non-compliance</td>
<td id="policy-action" style="padding:10px 15px;"></td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Status</td>
<td id="policy-status" style="padding:10px 15px;"></td>
</tr>
<tr role="row" id="users-row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Assigned Users</td>
<td id="policy-users" style="padding:10px 15px;"></td>
</tr>
<tr role="row" id="roles-row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Assigned Roles</td>
<td id="policy-roles" style="padding:10px 15px;"></td>
</tr>
</tbody>
</table>
{{/defineZone}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Description
</div>
<div class="add-margin-top-4x">
<div id="policy-description" class="panel-title-description"></div>
</div>
<br>
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Profile Information
</div>
<div class="add-margin-top-4x">
<div id="policy-profile-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-advance-operations">
<div class='wr-advance-operations-init'>
<br/>
<i class='fw fw-settings fw-spin fw-2x'></i>
Loading Platform Features . . .
<br/>
<br/>
</div>
<div id="device-type-policy-operations" class="hidden">
</div>
<div id="generic-policy-operations" class="hidden">
{{unit "cdmf.unit.device.type.generic.policy-wizard"}}
</div>
</div>
</div>
</div>
</div>
</div>
{{/zone}}
{{#zone "bottomJs"}}
{{js "js/view.js"}}
{{/zone}}

@ -0,0 +1,27 @@
/*
* 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.
*/
function onRequest(context) {
var utility = require("/app/modules/utility.js")["utility"];
var deviceType = context.uriParams.deviceType;
var deviceId = context.uriParams.deviceId;
return {"deviceTypePolicyView": utility.getTenantedDeviceUnitName(deviceType, deviceId,"policy-view")};
}

@ -0,0 +1,25 @@
{{!
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.
}}
{{#zone "topCss"}}
{{css "css/codemirror.css"}}
{{/zone}}
{{#zone "bottomJs"}}
{{js "js/codemirror.js"}}
{{js "js/javascript.js"}}
{{/zone}}

@ -0,0 +1,784 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function expressionAllowed(stream, state, backUp) {
return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
// Tokenizer
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
"await": C, "async": kw("async")
};
// Extend the 'normal' keywords with the TypeScript language extensions
if (isTS) {
var type = {type: "variable", style: "variable-3"};
var tsKeywords = {
// object-like things
"interface": kw("class"),
"implements": C,
"namespace": C,
"module": kw("module"),
"enum": kw("module"),
"type": kw("type"),
// scope modifiers
"public": kw("modifier"),
"private": kw("modifier"),
"protected": kw("modifier"),
"abstract": kw("modifier"),
// operators
"as": operator,
// types
"string": type, "number": type, "boolean": type, "any": type
};
for (var attr in tsKeywords) {
jsKeywords[attr] = tsKeywords[attr];
}
}
return jsKeywords;
}();
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
if (!escaped) {
if (next == "/" && !inSet) return;
if (next == "[") inSet = true;
else if (inSet && next == "]") inSet = false;
}
escaped = !escaped && next == "\\";
}
}
// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;
function ret(tp, style, cont) {
type = tp; content = cont;
return style;
}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
return ret("number", "number");
} else if (ch == "." && stream.match("..")) {
return ret("spread", "meta");
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return ret(ch);
} else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator");
} else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
} else if (ch == "0" && stream.eat(/o/i)) {
stream.eatWhile(/[0-7]/i);
return ret("number", "number");
} else if (ch == "0" && stream.eat(/b/i)) {
stream.eatWhile(/[01]/i);
return ret("number", "number");
} else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
return ret("number", "number");
} else if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
} else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream);
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
state.tokenize = tokenQuasi;
return tokenQuasi(stream, state);
} else if (ch == "#") {
stream.skipToEnd();
return ret("error", "error");
} else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
ret("variable", "variable", word);
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next;
if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
state.tokenize = tokenBase;
return ret("jsonld-keyword", "meta");
}
while ((next = stream.next()) != null) {
if (next == quote && !escaped) break;
escaped = !escaped && next == "\\";
}
if (!escaped) state.tokenize = tokenBase;
return ret("string", "string");
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
}
function tokenQuasi(stream, state) {
var escaped = false, next;
while ((next = stream.next()) != null) {
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
state.tokenize = tokenBase;
break;
}
escaped = !escaped && next == "\\";
}
return ret("quasi", "string-2", stream.current());
}
var brackets = "([{}])";
// This is a crude lookahead trick to try and notice that we're
// parsing the argument patterns for a fat-arrow function before we
// actually hit the arrow token. It only works if the arrow is on
// the same line as the arguments and there's no strange noise
// (comments) in between. Fallback is to only notice when we hit the
// arrow, and not declare the arguments as locals for the arrow
// body.
function findFatArrow(stream, state) {
if (state.fatArrowAt) state.fatArrowAt = null;
var arrow = stream.string.indexOf("=>", stream.start);
if (arrow < 0) return;
if (isTS) { // Try to skip TypeScript return type declarations after the arguments
var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
if (m) arrow = m.index
}
var depth = 0, sawSomething = false;
for (var pos = arrow - 1; pos >= 0; --pos) {
var ch = stream.string.charAt(pos);
var bracket = brackets.indexOf(ch);
if (bracket >= 0 && bracket < 3) {
if (!depth) { ++pos; break; }
if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
} else if (bracket >= 3 && bracket < 6) {
++depth;
} else if (wordRE.test(ch)) {
sawSomething = true;
} else if (/["'\/]/.test(ch)) {
return;
} else if (sawSomething && !depth) {
++pos;
break;
}
}
if (sawSomething && !depth) state.fatArrowAt = pos;
}
// Parser
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
this.column = column;
this.type = type;
this.prev = prev;
this.info = info;
if (align != null) this.align = align;
}
function inScope(state, varname) {
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) {
for (var v = cx.vars; v; v = v.next)
if (v.name == varname) return true;
}
}
function parseJS(state, style, type, content, stream) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
while(true) {
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
if (combinator(type, content)) {
while(cc.length && cc[cc.length - 1].lex)
cc.pop()();
if (cx.marked) return cx.marked;
if (type == "variable" && inScope(state, content)) return "variable-2";
return style;
}
}
}
// Combinator utils
var cx = {state: null, column: null, marked: null, cc: null};
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function register(varname) {
function inList(list) {
for (var v = list; v; v = v.next)
if (v.name == varname) return true;
return false;
}
var state = cx.state;
cx.marked = "def";
if (state.context) {
if (inList(state.localVars)) return;
state.localVars = {name: varname, next: state.localVars};
} else {
if (inList(state.globalVars)) return;
if (parserConfig.globalVars)
state.globalVars = {name: varname, next: state.globalVars};
}
}
// Combinators
var defaultVars = {name: "this", next: {name: "arguments"}};
function pushcontext() {
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
cx.state.localVars = defaultVars;
}
function popcontext() {
cx.state.localVars = cx.state.context.vars;
cx.state.context = cx.state.context.prev;
}
function pushlex(type, info) {
var result = function() {
var state = cx.state, indent = state.indented;
if (state.lexical.type == "stat") indent = state.lexical.indented;
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
indent = outer.indented;
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
};
result.lex = true;
return result;
}
function poplex() {
var state = cx.state;
if (state.lexical.prev) {
if (state.lexical.type == ")")
state.indented = state.lexical.indented;
state.lexical = state.lexical.prev;
}
}
poplex.lex = true;
function expect(wanted) {
function exp(type) {
if (type == wanted) return cont();
else if (wanted == ";") return pass();
else return cont(exp);
};
return exp;
}
function statement(type, value) {
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
if (type == "variable") return cont(pushlex("stat"), maybelabel);
if (type == "switch") return cont(pushlex("form"), parenExpr, pushlex("}", "switch"), expect("{"),
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
if (type == "class") return cont(pushlex("form"), className, poplex);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
if (type == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
if (type == "async") return cont(statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
return expressionInner(type, false);
}
function expressionNoComma(type) {
return expressionInner(type, true);
}
function parenExpr(type) {
if (type != "(") return pass()
return cont(pushlex(")"), expression, expect(")"), poplex)
}
function expressionInner(type, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
if (type == "class") return cont(pushlex("form"), classExpression, poplex);
if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
if (type == "quasi") { return pass(quasi, me); }
if (type == ";") return;
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
}
function quasi(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi);
return cont(expression, continueQuasi);
}
function continueQuasi(type) {
if (type == "}") {
cx.marked = "string-2";
cx.state.tokenize = tokenQuasi;
return cont(quasi);
}
}
function arrowBody(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expression);
}
function arrowBodyNoComma(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expressionNoComma);
}
function maybeTarget(noComma) {
return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target);
else return pass(noComma ? expressionNoComma : expression);
};
}
function target(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
}
function targetNoComma(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
return pass(maybeoperatorComma, expect(";"), poplex);
}
function property(type) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
if (type == "async") {
cx.marked = "property";
return cont(objprop);
} else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
} else if (type == "modifier") {
return cont(objprop)
} else if (type == "[") {
return cont(expression, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expression);
} else if (type == ":") {
return pass(afterprop)
}
}
function getterSetter(type) {
if (type != "variable") return pass(afterprop);
cx.marked = "property";
return cont(functiondef);
}
function afterprop(type) {
if (type == ":") return cont(expressionNoComma);
if (type == "(") return pass(functiondef);
}
function commasep(what, end) {
function proceed(type, value) {
if (type == ",") {
var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
return cont(function(type, value) {
if (type == end || value == end) return pass()
return pass(what)
}, proceed);
}
if (type == end || value == end) return cont();
return cont(expect(end));
}
return function(type, value) {
if (type == end || value == end) return cont();
return pass(what, proceed);
};
}
function contCommasep(what, end, info) {
for (var i = 3; i < arguments.length; i++)
cx.cc.push(arguments[i]);
return cont(pushlex(end, info), commasep(what, end), poplex);
}
function block(type) {
if (type == "}") return cont();
return pass(statement, block);
}
function maybetype(type, value) {
if (isTS) {
if (type == ":") return cont(typeexpr);
if (value == "?") return cont(maybetype);
}
}
function typeexpr(type) {
if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);}
if (type == "{") return cont(commasep(typeprop, "}"))
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
}
function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr)
}
function typeprop(type) {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"
return cont(typeprop)
} else if (type == ":") {
return cont(typeexpr)
}
}
function typearg(type) {
if (type == "variable") return cont(typearg)
else if (type == ":") return cont(typeexpr)
}
function afterType(type, value) {
if (value == "<") return cont(commasep(typeexpr, ">"), afterType)
if (type == "[") return cont(expect("]"), afterType)
}
function vardef() {
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
if (type == "modifier") return cont(pattern)
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
return cont(maybeAssign);
}
if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern);
if (type == "}") return pass();
return cont(expect(":"), pattern, maybeAssign);
}
function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma);
}
function vardefCont(type) {
if (type == ",") return cont(vardef);
}
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
}
function forspec(type) {
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef, expect(";"), forspec2);
if (type == ";") return cont(forspec2);
if (type == "variable") return cont(formaybeinof);
return pass(expression, expect(";"), forspec2);
}
function formaybeinof(_type, value) {
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return cont(maybeoperatorComma, forspec2);
}
function forspec2(type, value) {
if (type == ";") return cont(forspec3);
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return pass(expression, expect(";"), forspec3);
}
function forspec3(type) {
if (type != ")") cont(expression);
}
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
}
function funarg(type) {
if (type == "spread") return cont(funarg);
return pass(pattern, maybetype, maybeAssign);
}
function classExpression(type, value) {
// Class expressions may have an optional name.
if (type == "variable") return className(type, value);
return classNameAfter(type, value);
}
function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);}
}
function classNameAfter(type, value) {
if (value == "extends" || value == "implements") return cont(isTS ? typeexpr : expression, classNameAfter);
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
if (type == "variable" || cx.style == "keyword") {
if ((value == "static" || value == "get" || value == "set" ||
(isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
cx.marked = "keyword";
return cont(classBody);
}
cx.marked = "property";
return cont(isTS ? classfield : functiondef, classBody);
}
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (type == ";") return cont(classBody);
if (type == "}") return cont();
}
function classfield(type, value) {
if (value == "?") return cont(classfield)
if (type == ":") return cont(typeexpr, maybeAssign)
return pass(functiondef)
}
function afterExport(_type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
return pass(statement);
}
function afterImport(type) {
if (type == "string") return cont();
return pass(importSpec, maybeFrom);
}
function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}");
if (type == "variable") register(value);
if (value == "*") cx.marked = "keyword";
return cont(maybeAs);
}
function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
}
function maybeFrom(_type, value) {
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
}
function arrayLiteral(type) {
if (type == "]") return cont();
return pass(commasep(expressionNoComma, "]"));
}
function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," ||
isOperatorChar.test(textAfter.charAt(0)) ||
/[,.]/.test(textAfter.charAt(0));
}
// Interface
return {
startState: function(basecolumn) {
var state = {
tokenize: tokenBase,
lastType: "sof",
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: basecolumn || 0
};
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
state.globalVars = parserConfig.globalVars;
return state;
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
findFatArrow(stream, state);
}
if (state.tokenize != tokenComment && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
if (state.tokenize == tokenComment) return CodeMirror.Pass;
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
// Kludge to prevent 'maybelse' from blocking lexical scope pops
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
else if (c != maybeelse) break;
}
while ((lexical.type == "stat" || lexical.type == "form") &&
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
(top == maybeoperatorComma || top == maybeoperatorNoComma) &&
!/^[,\.=+\-*:?[\(]/.test(textAfter))))
lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
},
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
helperType: jsonMode ? "json" : "javascript",
jsonldMode: jsonldMode,
jsonMode: jsonMode,
expressionAllowed: expressionAllowed,
skipExpression: function(state) {
var top = state.cc[state.cc.length - 1]
if (top == expression || top == expressionNoComma) state.cc.pop()
}
};
});
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
});

@ -243,7 +243,7 @@
<div id="device-type-policy-operations" class="hidden">
</div>
<div id="generic-policy-operations" class="hidden">
{{unit "cdmf.unit.device.type.generic.policy-wizard"}}
{{unit "cdmf.unit.device.type.generic.policy-edit"}}
</div>
</div>
<div class="wr-input-control wr-btn-grp">

@ -22,9 +22,9 @@ var stepForwardFrom = {};
var stepBackFrom = {};
var policy = {};
var currentlyEffected = {};
var validateInline = {};
var clearInline = {};
var hasPolicyProfileScript = false;
var enableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
@ -195,6 +195,7 @@ skipStep["policy-platform"] = function (policyPayloadObj) {
$(".policy-platform").addClass("hidden");
$.isResourceExists(policyOperationsScriptSrc, function (status) {
if (status) {
hasPolicyProfileScript = true;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = policyOperationsScriptSrc;
@ -222,17 +223,23 @@ skipStep["policy-platform"] = function (policyPayloadObj) {
}
$(".wr-advance-operations-init").addClass("hidden");
});
if(!hasPolicyProfileScript) {
populateGenericProfileOperations(policyPayloadObj["profile"]["profileFeaturesList"]);
}
};
/**
* Forward action of policy profile page. Generates policy profile payload.
*/
stepForwardFrom["policy-profile"] = function () {
if (hasPolicyProfileScript) {
/*
generatePolicyProfile() function should be implemented in plugin side and should include the logic to build the
policy profile object.
*/
policy["profile"] = generatePolicyProfile();
}
// updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
};
@ -420,20 +427,26 @@ var getParameterByName = function (name) {
};
var updatePolicy = function (policy, state) {
var profilePayloads;
if (hasPolicyProfileScript) {
/*
generateProfileFeaturesList() should be implemented in the plugin side and should include logic to build the
profilePayloads array which contains objects, {featureCode:"value", deviceType:"value", content:"value"}.
policy["profile"] object will be available for the method which returns from the generatePolicyProfile() function.
*/
var profilePayloads = generateProfileFeaturesList();
profilePayloads = generateProfileFeaturesList();
$.each(profilePayloads, function (i, item) {
$.each(item.content, function (key, value) {
//cannot add a true check since it will catch value = false as well
if (value === null || value === undefined || value === "") {
item.content[key] = null;
}
});
});
} else {
profilePayloads = generateGenericPayload();
}
var payload = {
"policyName": policy["policyName"],

@ -17,6 +17,7 @@
*/
var policy = {};
var hasPolicyProfileScript = false;
var displayPolicy = function (policyPayloadObj) {
policy["name"] = policyPayloadObj["policyName"];
@ -82,6 +83,7 @@ var displayPolicy = function (policyPayloadObj) {
$(".policy-platform").addClass("hidden");
$.isResourceExists(policyOperationsScriptSrc, function (status) {
if (status) {
hasPolicyProfileScript = true;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = policyOperationsScriptSrc;
@ -109,6 +111,10 @@ var displayPolicy = function (policyPayloadObj) {
}
$(".wr-advance-operations-init").addClass("hidden");
});
if(!hasPolicyProfileScript) {
populateGenericProfileOperations(policyPayloadObj["profile"]["profileFeaturesList"]);
}
};
/**

@ -70,7 +70,7 @@
<div id="device-type-policy-operations" class="hidden">
</div>
<div id="generic-policy-operations" class="hidden">
{{unit "cdmf.unit.device.type.generic.policy-wizard"}}
{{unit "cdmf.unit.device.type.generic.policy-view"}}
</div>
</div>
</div>

@ -35,7 +35,7 @@
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4 id="modal-content-text"></h4>
<div id="modal-content-text"></div>
</div>
<div class="modal-footer" id="modal-footer-content"></div>
</div>

@ -23,7 +23,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>email-sender</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>dynamic-client-registration</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>dynamic-client-registration</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -132,7 +132,7 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
<scope>provided</scope>
<exclusions>

@ -21,13 +21,13 @@
<parent>
<artifactId>dynamic-client-registration</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.dynamic.client.registration</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Dynamic client registration service</name>
<description>WSO2 Carbon - Dynamic Client Registration Service</description>
@ -62,13 +62,9 @@
org.osgi.framework,
org.osgi.service.component,
org.wso2.carbon.context,
org.wso2.carbon.identity.application.common,
org.wso2.carbon.identity.application.common.model,
org.wso2.carbon.identity.application.mgt,
org.wso2.carbon.identity.application.mgt.stub,
org.wso2.carbon.identity.base,
org.wso2.carbon.identity.oauth,
org.wso2.carbon.identity.oauth.dto,
org.wso2.carbon.identity.application.*; version="${carbon.identity.imp.pkg.version}",
org.wso2.carbon.identity.base; version="${carbon.identity.imp.pkg.version}",
org.wso2.carbon.identity.oauth.*; version="${carbon.identity-inbound-auth-oauth.imp.pkg.version}",
org.wso2.carbon.identity.sso.saml.admin,
org.wso2.carbon.identity.sso.saml.dto,
org.wso2.carbon.registry.api,
@ -98,15 +94,15 @@
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
<artifactId>org.wso2.carbon.identity.oauth</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.inbound.auth.saml2</groupId>
<artifactId>org.wso2.carbon.identity.sso.saml</artifactId>
</dependency>
<dependency>

@ -21,13 +21,13 @@
<parent>
<artifactId>dynamic-client-registration</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.dynamic.client.web.app.registration</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Dynamic client web app registration</name>
<description>WSO2 Carbon - Dynamic Client Web-app Registration Service</description>
@ -99,15 +99,15 @@
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
<artifactId>org.wso2.carbon.identity.oauth</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.core</artifactId>
</dependency>
<dependency>

@ -22,14 +22,14 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>identity-extensions</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>dynamic-client-registration</artifactId>
<version>2.0.4-SNAPSHOT</version>
<version>2.0.6-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Dynamic client registration</name>
<url>http://wso2.org</url>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save