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

revert-70aa11f8
Menaka Jayawardena 8 years ago
commit 84a0b398fe

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - API Application Management API</name>

@ -37,7 +37,6 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Arrays;
@ -66,7 +65,8 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
applicationName, APIUtil.getAllowedApisTags().toArray(new String[APIUtil.getAllowedApisTags().size()]),
ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, false);
ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, false,
ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD);
return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build();
} catch (APIManagerException e) {
String msg = "Error occurred while registering an application '" + applicationName + "'";
@ -98,6 +98,12 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
}
String username = APIUtil.getAuthenticatedUser() + "@" + APIUtil.getTenantDomainOftheUser();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String validityPeriod;
if (registrationProfile.getValidityPeriod() == null) {
validityPeriod = ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD;
} else {
validityPeriod = registrationProfile.getValidityPeriod();
}
if (registrationProfile.isMappingAnExistingOAuthApp()) {
JSONObject jsonStringObject = new JSONObject();
jsonStringObject.put(ApiApplicationConstants.JSONSTRING_USERNAME_TAG, username);
@ -106,8 +112,7 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
jsonStringObject.put(ApiApplicationConstants.OAUTH_CLIENT_ID, registrationProfile.getConsumerKey());
jsonStringObject.put(ApiApplicationConstants.OAUTH_CLIENT_SECRET,
registrationProfile.getConsumerSecret());
jsonStringObject.put(ApiApplicationConstants.JSONSTRING_VALIDITY_PERIOD_TAG,
ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD);
jsonStringObject.put(ApiApplicationConstants.JSONSTRING_VALIDITY_PERIOD_TAG, validityPeriod);
apiManagementProviderService.registerExistingOAuthApplicationToAPIApplication(
jsonStringObject.toJSONString(), registrationProfile.getApplicationName(),
registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains(),
@ -116,7 +121,8 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
} else {
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
registrationProfile.getApplicationName(), registrationProfile.getTags(),
ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, false);
ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username,
registrationProfile.isAllowedToAllDomains(), validityPeriod);
return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build();
}
} catch (APIManagerException e) {

@ -41,6 +41,8 @@ public class RegistrationProfile {
private boolean isMappingAnExistingOAuthApp;
private String consumerKey;
private String consumerSecret;
@XmlElement(required = false)
private String validityPeriod;
public String getApplicationName() {
return applicationName;
@ -89,4 +91,12 @@ public class RegistrationProfile {
public void setConsumerSecret(String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public String getValidityPeriod() {
return validityPeriod;
}
public void setValidityPeriod(String validityPeriod) {
this.validityPeriod = validityPeriod;
}
}

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

@ -34,11 +34,14 @@ public interface APIManagementProviderService {
* @param tags tags of the apis that application needs to be subscribed.
* @param keyType of the application.
* @param username to whom the application is created
* @param isAllowedAllDomains application is allowed to all the tenants
* @param validityTime validity period of the application
* @return consumerkey and secrete of the created application.
* @throws APIManagerException
*/
ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[],
String keyType, String username, boolean isAllowedAllDomains)
String keyType, String username, boolean isAllowedAllDomains,
String validityTime)
throws APIManagerException;
/**

@ -133,7 +133,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
@Override
public ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[],
String keyType, String username,
boolean isAllowedAllDomains)
boolean isAllowedAllDomains, String validityTime)
throws APIManagerException {
try {
APIManagerUtil.loadTenantRegistry();
@ -172,7 +172,6 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
} else {
allowedDomains[0] = APIManagerUtil.getTenantDomain();
}
String validityTime = "3600";
String ownerJsonString = "{\"username\":\"" + username + "\"}";
Map<String, Object> keyDetails = apiConsumer.requestApprovalForApplicationRegistration(username,
apiApplicationName,

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

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apimgt-extensions</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -34,8 +34,8 @@ import javax.xml.bind.annotation.XmlType;
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="jndiConfig" type="{}jndiConfig"/>
* &lt;element name="tableConfig" type="{}tableConfig"/>
* &lt;element name="JndiConfig" type="{}JndiConfig"/>
* &lt;element name="TableConfig" type="{}TableConfig"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
@ -51,9 +51,10 @@ import javax.xml.bind.annotation.XmlType;
})
public class DataSource {
@XmlElement(required = true)
@XmlElement(name = "JndiConfig", required = true)
protected JndiConfig jndiConfig;
@XmlElement(required = true)
@XmlElement(name = "TableConfig", required = true)
protected TableConfig tableConfig;
/**

@ -0,0 +1,68 @@
/*
* 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.extensions.device.type.deployer.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for Device type authorization requirement.
* <p/>
* <p>The following schema fragment specifies the expected content contained within this class.
* <p/>
* <pre>
* &lt;complexType name="DeviceAuthorizationConfig">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="authorizationRequired" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DeviceAuthorizationConfig", propOrder = {
"authorizationRequired"
})
public class DeviceAuthorizationConfig {
@XmlElement(name = "authorizationRequired")
protected boolean authorizationRequired;
/**
* Gets the value of the sharedWithAllTenants property.
*/
public boolean isAuthorizationRequired() {
return authorizationRequired;
}
/**
* Sets the value of the sharedWithAllTenants property.
*/
public void setAuthorizationRequired(boolean authorizationRequired) {
this.authorizationRequired = authorizationRequired;
}
}

@ -27,9 +27,9 @@ import javax.xml.bind.annotation.XmlRootElement;
/**
* <p>Java class for DeviceTypeConfiguration complex type.
*
* <p/>
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <p/>
* <pre>
* &lt;complexType name="DeviceTypeConfiguration">
* &lt;complexContent>
@ -41,14 +41,13 @@ import javax.xml.bind.annotation.XmlRootElement;
* &lt;element name="PushNotificationProvider" type="{}PushNotificationProvider"/>
* &lt;element name="License" type="{}License"/>
* &lt;element name="DataSource" type="{}DataSource"/>
* &lt;element name="DeviceAuthorizationConfig" type="{}DeviceAuthorizationConfig"/>
* &lt;/sequence>
* &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "DeviceTypeConfiguration")
@ -66,16 +65,42 @@ public class DeviceTypeConfiguration {
protected License license;
@XmlElement(name = "DataSource", required = true)
protected DataSource dataSource;
@XmlElement(name = "TaskConfiguration", required = true)
private TaskConfiguration taskConfiguration;
@XmlElement(name = "DeviceAuthorizationConfig", required = true)
protected DeviceAuthorizationConfig deviceAuthorizationConfig;
@XmlAttribute(name = "name")
protected String name;
/**
* Gets the value of the deviceDetails property.
*
* Gets the value of the taskConfiguration property.
*
* @return
* possible object is
* {@link DeviceDetails }
*
* {@link TaskConfiguration }
*
*/
public TaskConfiguration getTaskConfiguration() {
return taskConfiguration;
}
/**
* Sets the value of the taskConfiguration property.
*
* @param taskConfiguration
* allowed object is
* {@link TaskConfiguration }
*
*/
public void setTaskConfiguration(TaskConfiguration taskConfiguration) {
this.taskConfiguration = taskConfiguration;
}
/**
* Gets the value of the deviceDetails property.
*
* @return possible object is
* {@link DeviceDetails }
*/
public DeviceDetails getDeviceDetails() {
return deviceDetails;
@ -83,11 +108,9 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the deviceDetails property.
*
* @param value
* allowed object is
* {@link DeviceDetails }
*
*
* @param value allowed object is
* {@link DeviceDetails }
*/
public void setDeviceDetails(DeviceDetails value) {
this.deviceDetails = value;
@ -95,11 +118,9 @@ public class DeviceTypeConfiguration {
/**
* Gets the value of the features property.
*
* @return
* possible object is
* {@link Features }
*
*
* @return possible object is
* {@link Features }
*/
public Features getFeatures() {
return features;
@ -107,11 +128,9 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the features property.
*
* @param value
* allowed object is
* {@link Features }
*
*
* @param value allowed object is
* {@link Features }
*/
public void setFeatures(Features value) {
this.features = value;
@ -119,11 +138,9 @@ public class DeviceTypeConfiguration {
/**
* Gets the value of the provisioningConfig property.
*
* @return
* possible object is
* {@link ProvisioningConfig }
*
*
* @return possible object is
* {@link ProvisioningConfig }
*/
public ProvisioningConfig getProvisioningConfig() {
return provisioningConfig;
@ -131,11 +148,9 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the provisioningConfig property.
*
* @param value
* allowed object is
* {@link ProvisioningConfig }
*
*
* @param value allowed object is
* {@link ProvisioningConfig }
*/
public void setProvisioningConfig(ProvisioningConfig value) {
this.provisioningConfig = value;
@ -143,11 +158,9 @@ public class DeviceTypeConfiguration {
/**
* Gets the value of the pushNotificationProvider property.
*
* @return
* possible object is
* {@link PushNotificationProvider }
*
*
* @return possible object is
* {@link PushNotificationProvider }
*/
public PushNotificationProvider getPushNotificationProvider() {
return pushNotificationProvider;
@ -155,11 +168,9 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the pushNotificationProvider property.
*
* @param value
* allowed object is
* {@link PushNotificationProvider }
*
*
* @param value allowed object is
* {@link PushNotificationProvider }
*/
public void setPushNotificationProvider(PushNotificationProvider value) {
this.pushNotificationProvider = value;
@ -167,11 +178,9 @@ public class DeviceTypeConfiguration {
/**
* Gets the value of the license property.
*
* @return
* possible object is
* {@link License }
*
*
* @return possible object is
* {@link License }
*/
public License getLicense() {
return license;
@ -179,11 +188,9 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the license property.
*
* @param value
* allowed object is
* {@link License }
*
*
* @param value allowed object is
* {@link License }
*/
public void setLicense(License value) {
this.license = value;
@ -191,11 +198,9 @@ public class DeviceTypeConfiguration {
/**
* Gets the value of the dataSource property.
*
* @return
* possible object is
* {@link DataSource }
*
*
* @return possible object is
* {@link DataSource }
*/
public DataSource getDataSource() {
return dataSource;
@ -203,11 +208,9 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the dataSource property.
*
* @param value
* allowed object is
* {@link DataSource }
*
*
* @param value allowed object is
* {@link DataSource }
*/
public void setDataSource(DataSource value) {
this.dataSource = value;
@ -215,11 +218,9 @@ public class DeviceTypeConfiguration {
/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*
* @return possible object is
* {@link String }
*/
public String getName() {
return name;
@ -227,14 +228,32 @@ public class DeviceTypeConfiguration {
/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*
* @param value allowed object is
* {@link String }
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the authorizationRequired property.
*
* @return possible object is
* {@link DeviceAuthorizationConfig }
*/
public DeviceAuthorizationConfig getDeviceAuthorizationConfig() {
return deviceAuthorizationConfig;
}
/**
* Sets the value of the provisioningConfig property.
*
* @param value allowed object is
* {@link DeviceAuthorizationConfig }
*/
public void setDeviceAuthorizationConfig(DeviceAuthorizationConfig value) {
this.deviceAuthorizationConfig = value;
}
}

@ -30,7 +30,7 @@ import javax.xml.bind.annotation.XmlType;
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="jndiConfig">
* &lt;complexType name="JndiConfig">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
@ -44,12 +44,12 @@ import javax.xml.bind.annotation.XmlType;
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "jndiConfig", propOrder = {
@XmlType(name = "JndiConfig", propOrder = {
"name"
})
public class JndiConfig {
@XmlElement(required = true)
@XmlElement(name = "Name", required = true)
protected String name;
/**

@ -40,6 +40,7 @@ import javax.xml.bind.annotation.XmlType;
* &lt;/sequence>
* &lt;attribute name="context" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="method" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
@ -62,6 +63,32 @@ public class Operation {
protected String context;
@XmlAttribute(name = "method")
protected String method;
@XmlAttribute(name = "type")
protected String type;
/**
* Gets the value of the Content Type property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getType() {
return type;
}
/**
* Sets the value of the Content Type property.
*
* @param type
* allowed object is
* {@link String }
*
*/
public void setType(String type) {
this.type = type;
}
/**
* Gets the value of the queryParameters property.

@ -46,7 +46,7 @@ import javax.xml.bind.annotation.XmlType;
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "tableConfig", propOrder = {
@XmlType(name = "TableConfig", propOrder = {
"table"
})
public class TableConfig {

@ -0,0 +1,102 @@
/*
* 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.extensions.device.type.deployer.config;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/**
*
*/
@XmlRootElement(name = "TaskConfiguration")
public class TaskConfiguration {
private boolean enabled;
private int frequency;
private String taskClazz;
private List<Operation> operations;
@XmlElement(name = "Enable", required = true)
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@XmlElement(name = "Frequency", required = true)
public int getFrequency() {
return frequency;
}
public void setFrequency(int frequency) {
this.frequency = frequency;
}
@XmlElement(name = "TaskClass", required = true)
public String getTaskClazz() {
return taskClazz;
}
public void setTaskClazz(String taskClazz) {
this.taskClazz = taskClazz;
}
@XmlElementWrapper(name="Operations")
@XmlElement(name = "Operation", required = true)
public List<Operation> getOperations() {
return operations;
}
public void setOperations(List<Operation> operations) {
this.operations = operations;
}
@XmlRootElement(name = "Operation")
public static class Operation {
private String operationName;
private int recurrency;
@XmlElement(name = "Name", required = true)
public String getOperationName() {
return operationName;
}
public void setOperationName(String operationName) {
this.operationName = operationName;
}
@XmlElement(name = "RecurrentTimes", required = true)
public int getRecurrency() {
return recurrency;
}
public void setRecurrency(int recurrency) {
this.recurrency = recurrency;
}
}
}

@ -30,11 +30,8 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceDetails;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.Table;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.*;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.util.DeviceTypePluginConstants;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.Feature;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.exception.DeviceTypeDeployerFileException;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.exception.DeviceTypeMgtPluginException;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.template.dao.DeviceDAODefinition;
@ -65,18 +62,26 @@ public class DeviceTypeManager implements DeviceManager {
private DeviceTypePluginDAOManager deviceTypePluginDAOManager;
private LicenseManager licenseManager;
private boolean propertiesExist;
private boolean requiredDeviceTypeAuthorization;
private FeatureManager featureManager;
public DeviceTypeManager(DeviceTypeConfigIdentifier deviceTypeConfigIdentifier,
DeviceTypeConfiguration deviceTypeConfiguration) {
DeviceTypeConfiguration deviceTypeConfiguration) {
deviceType = deviceTypeConfigIdentifier.getDeviceType();
if (deviceTypeConfiguration.getFeatures() != null && deviceTypeConfiguration.getFeatures().getFeature() != null ) {
if (deviceTypeConfiguration.getFeatures() != null && deviceTypeConfiguration.getFeatures().
getFeature() != null) {
List<Feature> features = deviceTypeConfiguration.getFeatures().getFeature();
if (features != null) {
featureManager = new ConfigurationBasedFeatureManager(features);
}
}
if (deviceTypeConfiguration.getDeviceAuthorizationConfig() != null) {
requiredDeviceTypeAuthorization = deviceTypeConfiguration.getDeviceAuthorizationConfig().
isAuthorizationRequired();
} else {
requiredDeviceTypeAuthorization = true;
}
//add license to registry.
this.licenseManager = new RegistryBasedLicenseManager();
try {
@ -120,11 +125,11 @@ public class DeviceTypeManager implements DeviceManager {
if (setupOption != null) {
if (log.isDebugEnabled()) {
log.debug("-Dsetup is enabled. Device management repository schema initialization is about " +
"to begin");
"to begin");
}
try {
DeviceTypeUtils.setupDeviceManagementSchema(datasourceName, deviceType,
deviceDAODefinition.getDeviceTableName());
deviceDAODefinition.getDeviceTableName());
} catch (DeviceTypeMgtPluginException e) {
log.error("Exception occurred while initializing device management database schema", e);
}
@ -346,7 +351,7 @@ public class DeviceTypeManager implements DeviceManager {
@Override
public boolean requireDeviceAuthorization() {
return true;
return requiredDeviceTypeAuthorization;
}
@Override
@ -370,7 +375,7 @@ public class DeviceTypeManager implements DeviceManager {
deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction();
} catch (DeviceTypeMgtPluginException e1) {
log.warn("Error occurred while roll back the update device info transaction : '" +
device.toString() + "'", e1);
device.toString() + "'", e1);
}
throw new DeviceManagementException(
"Error occurred while updating the " + deviceType + " device: '" +

@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.TaskOperation;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
@ -31,7 +32,9 @@ import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.DeviceTypeConfiguration;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.Property;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.PushNotificationProvider;
import org.wso2.carbon.device.mgt.extensions.device.type.deployer.config.TaskConfiguration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -48,6 +51,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
private PushNotificationConfig pushNotificationConfig;
private ProvisioningConfig provisioningConfig;
private String type;
private List<TaskOperation> taskOperations;
public DeviceTypeManagerService(DeviceTypeConfigIdentifier deviceTypeConfigIdentifier,
DeviceTypeConfiguration deviceTypeConfiguration) {
@ -55,6 +59,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
this.deviceManager = new DeviceTypeManager(deviceTypeConfigIdentifier, deviceTypeConfiguration);
this.setType(deviceTypeConfiguration.getName());
this.populatePushNotificationConfig(deviceTypeConfiguration.getPushNotificationProvider());
this.setTask(deviceTypeConfiguration);
}
@Override
@ -62,6 +67,28 @@ public class DeviceTypeManagerService implements DeviceManagementService {
return type;
}
@Override
public List<TaskOperation> getTasksForPlatform(){
return taskOperations;
}
private void setTask(DeviceTypeConfiguration deviceTypeConfiguration) {
//Read the config file and take the list of operations there in the config
TaskConfiguration taskConfiguration = deviceTypeConfiguration.getTaskConfiguration();
if (taskConfiguration != null) {
List<TaskConfiguration.Operation> ops = taskConfiguration.getOperations();
if (ops != null && !ops.isEmpty()) {
taskOperations = new ArrayList<>();
for (TaskConfiguration.Operation op : ops) {
TaskOperation taskOperation = new TaskOperation();
taskOperation.setTaskName(op.getOperationName());
taskOperation.setRecurrentTimes(op.getRecurrency());
taskOperations.add(taskOperation);
}
}
}
}
@Override
public void init() throws DeviceManagementException {
}

@ -69,7 +69,7 @@ public class DeviceTypePluginDAO {
device = new Device();
if (log.isDebugEnabled()) {
log.debug(deviceId + " data has been fetched from " + deviceDAODefinition.getDeviceTableName() +
" database.");
" database.");
}
List<Device.Property> properties = new ArrayList<>();
for (String columnName : deviceDAODefinition.getColumnNames()) {
@ -112,7 +112,7 @@ public class DeviceTypePluginDAO {
status = true;
if (log.isDebugEnabled()) {
log.debug("device " + device.getDeviceIdentifier() + " data has been" +
" added to the " + deviceDAODefinition.getDeviceTableName() + " database.");
" added to the " + deviceDAODefinition.getDeviceTableName() + " database.");
}
}
} catch (SQLException e) {
@ -170,7 +170,7 @@ public class DeviceTypePluginDAO {
status = true;
if (log.isDebugEnabled()) {
log.debug("device " + deviceId + " data has deleted from the " +
deviceDAODefinition.getDeviceTableName() + " table.");
deviceDAODefinition.getDeviceTableName() + " table.");
}
}
} catch (SQLException e) {
@ -241,7 +241,7 @@ public class DeviceTypePluginDAO {
private String getPropertString(List<Device.Property> properties, String propertyName) {
for (Device.Property property : properties) {
if (property.getName().equals(propertyName)) {
if (property.getName() != null && property.getName().equals(propertyName)) {
return property.getValue();
}
}
@ -257,7 +257,7 @@ public class DeviceTypePluginDAO {
+ getPreparedInputString(deviceDAODefinition.getColumnNames().size() + 1) + ")";
updateDBQueryForUpdateDevice = "UPDATE " + deviceDAODefinition.getDeviceTableName() + " SET "
+ getDeviceTableColumnNamesForUpdateQuery()+ " WHERE " + deviceDAODefinition.getPrimaryKey()
+ getDeviceTableColumnNamesForUpdateQuery() + " WHERE " + deviceDAODefinition.getPrimaryKey()
+ " = ?";
deleteDBQueryToRemoveDevicd = "DELETE FROM " + deviceDAODefinition.getDeviceTableName()

@ -38,6 +38,7 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
private List<Feature> features = new ArrayList<>();
private static final String METHOD = "method";
private static final String URI = "uri";
private static final String CONTENT_TYPE = "contentType";
private static final String PATH_PARAMS = "pathParams";
private static final String QUERY_PARAMS = "queryParams";
private static final String FORM_PARAMS = "formParams";
@ -55,6 +56,7 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
Map<String, Object> apiParams = new HashMap<>();
apiParams.put(METHOD, operation.getMethod().toUpperCase());
apiParams.put(URI, operation.getContext());
apiParams.put(CONTENT_TYPE, operation.getType());
List<String> pathParams = new ArrayList<>();
List<String> queryParams = new ArrayList<>();
List<String> formParams = new ArrayList<>();

@ -25,7 +25,7 @@
<Feature code="abc">
<Name>abc</Name>
<Description>this is a feature</Description>
<Operation context="/bulb/{state}" method="PUT">
<Operation context="/bulb/{state}" method="PUT" type="application/json">
<QueryParameters>
<Parameter>deviceId</Parameter>
</QueryParameters>
@ -63,6 +63,10 @@
<SharedWithAllTenants>false</SharedWithAllTenants>
</ProvisioningConfig>
<DeviceAuthorizationConfig>
<authorizationRequired>true</authorizationRequired>
</DeviceAuthorizationConfig>
<PushNotificationProvider type="MQTT">
<FileBasedProperties>true</FileBasedProperties>
<!--if file based properties is set to false then the configuration will be picked from platform configuration-->
@ -97,5 +101,20 @@
</Table>
</tableConfig>
</DataSource>
<TaskConfiguration>
<Operations>
<Operation>
<Name>DEVICE_INFO</Name>
<RecurrentTimes>1</RecurrentTimes>
</Operation>
<Operation>
<Name>APPLICATION_LIST</Name>
<RecurrentTimes>5</RecurrentTimes>
</Operation>
<Operation>
<Name>DEVICE_LOCATION</Name>
<RecurrentTimes>1</RecurrentTimes>
</Operation>
</Operations>
</TaskConfiguration>
</DeviceTypeConfiguration>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.jaxrs.beans;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.policy.mgt.common.DeviceGroupWrapper;
import javax.validation.constraints.Size;
import java.util.List;
@ -75,6 +76,10 @@ public class PolicyWrapper {
required = true)
private List<String> users;
@ApiModelProperty(name = "deviceGroups", value = "Lists out the groups on whose devices the policy is enforced",
required = true)
private List<DeviceGroupWrapper> deviceGroups;
public Profile getProfile() {
return profile;
}
@ -147,4 +152,12 @@ public class PolicyWrapper {
this.users = users;
}
public List<DeviceGroupWrapper> getDeviceGroups() {
return deviceGroups;
}
public void setDeviceGroups(List<DeviceGroupWrapper> deviceGroups) {
this.deviceGroups = deviceGroups;
}
}

@ -122,6 +122,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
policy.setRoles(policyWrapper.getRoles());
policy.setUsers(policyWrapper.getUsers());
policy.setCompliance(policyWrapper.getCompliance());
policy.setDeviceGroups(policyWrapper.getDeviceGroups());
//TODO iterates the device identifiers to create the object. need to implement a proper DAO layer here.
List<Device> devices = new ArrayList<Device>();
List<DeviceIdentifier> deviceIdentifiers = policyWrapper.getDeviceIdentifiers();

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

@ -0,0 +1,46 @@
/*
* 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.
*
*/
package org.wso2.carbon.device.mgt.common;
/**
*
*/
public class TaskOperation {
private String taskName;
private int recurrentTimes;
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public int getRecurrentTimes() {
return recurrentTimes;
}
public void setRecurrentTimes(int recurrentTimes) {
this.recurrentTimes = recurrentTimes;
}
}

@ -21,9 +21,12 @@ package org.wso2.carbon.device.mgt.common.spi;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.TaskOperation;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import java.util.List;
/**
* Composite interface that acts as the SPI exposing all device management as well as application management
* functionalities.
@ -34,6 +37,8 @@ public interface DeviceManagementService {
String getType();
List<TaskOperation> getTasksForPlatform();//getTasksConfiguraitons
DeviceManager getDeviceManager();
ApplicationManager getApplicationManager();

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

@ -105,6 +105,11 @@ public class GroupDAOImpl implements GroupDAO {
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
sql = "DELETE FROM DM_DEVICE_GROUP_POLICY WHERE DEVICE_GROUP_ID = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while removing mappings for group.'", e);
} finally {

@ -21,16 +21,25 @@ package org.wso2.carbon.device.mgt.core.operation.mgt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.TaskOperation;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.common.operation.mgt.*;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.ActivityStatus;
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.operation.mgt.OperationManager;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationContext;
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationExecutionFailedException;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
@ -43,6 +52,7 @@ import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationMappingDAO;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.util.OperationDAOUtil;
import org.wso2.carbon.device.mgt.core.operation.mgt.util.DeviceIDHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.util.OperationCreateTimeComparator;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager;
import org.wso2.carbon.device.mgt.core.task.impl.DeviceTaskManagerImpl;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
@ -51,7 +61,9 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class implements all the functionality exposed as part of the OperationManager. Any transaction initiated
@ -127,7 +139,7 @@ public class OperationManagerImpl implements OperationManager {
org.wso2.carbon.device.mgt.core.dto.operation.mgt.Operation operationDto =
OperationDAOUtil.convertOperation(operation);
int operationId = this.lookupOperationDAO(operation).addOperation(operationDto);
boolean isScheduledOperation = this.isTaskScheduledOperation(operation);
boolean isScheduledOperation = this.isTaskScheduledOperation(operation, deviceIds);
boolean isNotRepeated = false;
boolean hasExistingTaskOperation;
int enrolmentId;
@ -231,7 +243,7 @@ public class OperationManagerImpl implements OperationManager {
List<String> unAuthorizedDeviceList = new ArrayList<>();
DeviceIDHolder deviceIDHolder = new DeviceIDHolder();
try {
if (operation != null && isAuthenticationSkippedOperation(operation)) {
if (operation != null && isAuthenticationSkippedOperation(operation, deviceIds)) {
authorizedDeviceList = deviceIds;
} else {
boolean isAuthorized;
@ -873,11 +885,11 @@ public class OperationManagerImpl implements OperationManager {
return CarbonContext.getThreadLocalCarbonContext().getUsername();
}
private boolean isAuthenticationSkippedOperation(Operation operation) {
private boolean isAuthenticationSkippedOperation(Operation operation, List<DeviceIdentifier> deviceIds) {
//This is to check weather operations are coming from the task related to retrieving device information.
DeviceTaskManager taskManager = new DeviceTaskManagerImpl();
if (taskManager.isTaskOperation(operation.getCode())) {
if (taskManager.isTaskOperation(operation.getCode(), deviceIds)) {
return true;
}
@ -1021,14 +1033,37 @@ public class OperationManagerImpl implements OperationManager {
return resetStatus;
}
private boolean isTaskScheduledOperation(Operation operation) {
TaskConfiguration taskConfiguration = DeviceConfigurationManager.getInstance().getDeviceManagementConfig().
getTaskConfiguration();
for (TaskConfiguration.Operation op : taskConfiguration.getOperations()) {
if (operation.getCode().equals(op.getOperationName())) {
return true;
private boolean isTaskScheduledOperation(Operation operation, List<DeviceIdentifier> deviceIds) {
List<TaskOperation> taskOperations = new ArrayList<>();
Map<String, List<TaskOperation>> deviceTypeSpecificTasks = new HashMap<>();
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder.getInstance().
getDeviceManagementProvider();
deviceTypeSpecificTasks = deviceManagementProviderService.getTaskList();//Get task list from each device type
for(DeviceIdentifier deviceIdentifier : deviceIds){
String deviceType = deviceIdentifier.getType();
for(String dti : deviceTypeSpecificTasks.keySet()){
if (dti.equals(deviceType)) {
taskOperations = deviceTypeSpecificTasks.get(dti);
for(TaskOperation op : taskOperations){
if (operation.getCode().equals(op.getTaskName())) {
return true;
}
}
}
}
}
// TaskConfiguration taskConfiguration = DeviceConfigurationManager.getInstance().getDeviceManagementConfig().
// getTaskConfiguration();
// for (TaskConfiguration.Operation op : taskConfiguration.getOperations()) {
// if (operation.getCode().equals(op.getOperationName())) {
// return true;
// }
// }
return false;
}

@ -27,6 +27,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementExcept
import java.util.HashMap;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Proxy class for all Device Management related operations that take the corresponding plugin type in
@ -275,4 +276,6 @@ public interface DeviceManagementProviderService {
int getActivityCountUpdatedAfter(long timestamp) throws OperationManagementException;
Map<String, List<TaskOperation>> getTaskList();
}

@ -21,6 +21,7 @@ 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;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
@ -32,6 +33,7 @@ import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.TaskOperation;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
@ -1213,6 +1215,27 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return DeviceManagementDataHolder.getInstance().getOperationManager().getActivityCountUpdatedAfter(timestamp);
}
@Override
public Map<String, List<TaskOperation>> getTaskList() {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
Map<DeviceTypeIdentifier, DeviceManagementService> deviceManagementServiceMap =
pluginRepository.getAllDeviceManagementServices(tenantId);
DeviceManagementService dms;
String deviceType;
List<TaskOperation> taskOperations;
Map<String, List<TaskOperation>> deviceTypeSpecificTasks = new HashMap<>();
for(DeviceTypeIdentifier dti : deviceManagementServiceMap.keySet()){
dms = deviceManagementServiceMap.get(dti);
taskOperations = dms.getTasksForPlatform();
if (taskOperations != null) {
deviceType = dms.getType();
deviceTypeSpecificTasks.put(deviceType, taskOperations);
}
}
return deviceTypeSpecificTasks;
}
@Override
public List<Device> getDevicesOfUser(String username) throws DeviceManagementException {
List<Device> devices = new ArrayList<>();
@ -1903,6 +1926,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
defaultGroup = new DeviceGroup(groupName);
// Setting system level user (wso2.system.user) as the owner
defaultGroup.setOwner(CarbonConstants.REGISTRY_SYSTEM_USERNAME);
defaultGroup.setDescription("Default system group for devices with " + groupName + " ownership.");
try {
service.createGroup(defaultGroup, DeviceGroupConstants.Roles.DEFAULT_ADMIN_ROLE,
DeviceGroupConstants.Permissions.DEFAULT_ADMIN_PERMISSIONS);

@ -19,6 +19,8 @@
package org.wso2.carbon.device.mgt.core.task;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import java.util.List;
public interface DeviceTaskManager {
@ -29,8 +31,8 @@ public interface DeviceTaskManager {
* @return - list of Task Operations.
* @throws DeviceMgtTaskException
*/
List<TaskOperation> getOperationList() throws DeviceMgtTaskException;
List<org.wso2.carbon.device.mgt.common.TaskOperation> getOperationList(String deviceType)
throws DeviceMgtTaskException;
/**
* This method will take the monitoring frequency.
@ -66,7 +68,7 @@ public interface DeviceTaskManager {
* @return
* @throws DeviceMgtTaskException
*/
List<String> getValidOperationNames() throws DeviceMgtTaskException;
List<String> getValidOperationNames(String deviceType) throws DeviceMgtTaskException;
/**
* This method will check wheather give operation is added by the task.
@ -74,6 +76,6 @@ public interface DeviceTaskManager {
* @return - true or false
* @throws DeviceMgtTaskException
*/
boolean isTaskOperation(String opName);
boolean isTaskOperation(String opName, List<DeviceIdentifier> deviceIds);
}

@ -22,22 +22,27 @@ package org.wso2.carbon.device.mgt.core.task.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.TaskOperation;
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.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.task.TaskConfiguration;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException;
import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager;
import org.wso2.carbon.device.mgt.core.task.TaskOperation;
import org.wso2.carbon.device.mgt.core.task.Utils;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DeviceTaskManagerImpl implements DeviceTaskManager {
@ -47,34 +52,35 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
@Override
public List<TaskOperation> getOperationList() throws DeviceMgtTaskException {
TaskConfiguration taskConfiguration =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getTaskConfiguration();
//get device type specific operations
public List<TaskOperation> getOperationList(String deviceType) throws DeviceMgtTaskException {
List<TaskConfiguration.Operation> ops = taskConfiguration.getOperations();
List<TaskOperation> taskOperations = new ArrayList<>();
for (TaskConfiguration.Operation op : ops) {
TaskOperation taskOperation = new TaskOperation();
taskOperation.setTaskName(op.getOperationName());
taskOperation.setRecurrentTimes(op.getRecurrency());
taskOperation.setTaskPlatforms(op.getPlatforms());
taskOperations.add(taskOperation);
Map<String, List<TaskOperation>> deviceTypeSpecificTasks;
//This Map contains task list against device type
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder.getInstance().
getDeviceManagementProvider();
deviceTypeSpecificTasks = deviceManagementProviderService.getTaskList();//Get task list from each device type
for(String dti : deviceTypeSpecificTasks.keySet()){
if (dti.equals(deviceType)) {
taskOperations = deviceTypeSpecificTasks.get(dti);
}
}
return taskOperations;
}
public List<String> getPlatformsForOperations(String opName) {
private List<String> getDeviceTypes() {
List<String> operationPlatforms = new ArrayList<>();
TaskConfiguration taskConfiguration =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getTaskConfiguration();
List<TaskConfiguration.Operation> ops = taskConfiguration.getOperations();
for (TaskConfiguration.Operation op : ops) {
if (op.getOperationName().equals(opName)) {
List<String> platform = op.getPlatforms();
for (String operationPlatform : platform) {
operationPlatforms.add(operationPlatform);
}
}
Map<String, List<TaskOperation>> deviceTypeSpecificTasks;
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder.getInstance().
getDeviceManagementProvider();
deviceTypeSpecificTasks = deviceManagementProviderService.getTaskList();
Set<String> platformTypes = deviceTypeSpecificTasks.keySet();
for(String platformType : platformTypes ){
operationPlatforms.add(platformType);
}
return operationPlatforms;
}
@ -100,32 +106,31 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
@Override
public void addOperations() throws DeviceMgtTaskException {
List<String> deviceTypes;
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder.getInstance().
getDeviceManagementProvider();
try {
List<Device> devices;
List<String> operations = this.getValidOperationNames();
for (String taskOperation : operations) {
deviceTypes = getPlatformsForOperations(taskOperation);
for (String deviceType : deviceTypes) {
devices = deviceManagementProviderService.getAllDevices(deviceType);
if (!devices.isEmpty()) {
for (String str : operations) {
CommandOperation operation = new CommandOperation();
operation.setEnabled(true);
operation.setType(Operation.Type.COMMAND);
operation.setCode(str);
deviceManagementProviderService.addOperation(deviceType, operation,
DeviceManagerUtil.getValidDeviceIdentifiers(devices));
}
} else {
if (log.isDebugEnabled()) {
log.debug("No devices are available to perform the operations.");
}
}
}
List<String> operations;
List<String> deviceTypes = this.getDeviceTypes();//list available device types
for(String deviceType : deviceTypes){
operations = this.getValidOperationNames(deviceType); //list operations for each device type
devices = deviceManagementProviderService.getAllDevices(deviceType);//list devices for each type
if (!devices.isEmpty()) {
for (String str : operations) {
CommandOperation operation = new CommandOperation();
operation.setEnabled(true);
operation.setType(Operation.Type.COMMAND);
operation.setCode(str);
deviceManagementProviderService.addOperation(deviceType, operation,
DeviceManagerUtil.getValidDeviceIdentifiers(devices));
}
} else {
if (log.isDebugEnabled()) {
log.debug("No devices are available to perform the operations.");
}
}
}
} catch (InvalidDeviceException e) {
throw new DeviceMgtTaskException("Invalid DeviceIdentifiers found.", e);
@ -137,8 +142,9 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
}
@Override
public List<String> getValidOperationNames() throws DeviceMgtTaskException {
List<TaskOperation> taskOperations = this.getOperationList();
public List<String> getValidOperationNames(String deviceType) throws DeviceMgtTaskException {
List<TaskOperation> taskOperations = this.getOperationList(deviceType);
List<String> opNames = new ArrayList<>();
Long milliseconds = System.currentTimeMillis();
int frequency = this.getTaskFrequency();
@ -167,17 +173,22 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
@Override
public boolean isTaskOperation(String opName) {
try {
List<TaskOperation> taskOperations = this.getOperationList();
for (TaskOperation taop : taskOperations) {
if (taop.getTaskName().equalsIgnoreCase(opName)) {
return true;
public boolean isTaskOperation(String opName, List<DeviceIdentifier> deviceIds) {
for(DeviceIdentifier deviceIdentifier : deviceIds){
String deviceType = deviceIdentifier.getType();
try {
List<TaskOperation> taskOperations = this.getOperationList(deviceType);
for (TaskOperation taop : taskOperations) {
if (taop.getTaskName().equalsIgnoreCase(opName)) {
return true;
}
}
} catch (DeviceMgtTaskException e) {
// ignoring the error, no need to throw, If error occurs, return value will be false.
}
} catch (DeviceMgtTaskException e) {
// ignoring the error, no need to throw, If error occurs, return value will be false.
}
return false;
}

@ -39,6 +39,8 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
public static final String TASK_TYPE = "DEVICE_DETAILS";
public static final String TASK_NAME = "DEVICE_DETAILS_TASK";
public static final String TENANT_ID = "TENANT_ID";
private static String TASK_CLASS = "org.wso2.carbon.device.mgt.core.task.impl.DeviceDetailsRetrieverTask";
private DeviceTaskManager deviceTaskManager;
@ -75,7 +77,7 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
if (!taskManager.isTaskScheduled(TASK_NAME)) {
TaskInfo taskInfo = new TaskInfo(TASK_NAME, deviceTaskManager.getTaskImplementedClazz(),
TaskInfo taskInfo = new TaskInfo(TASK_NAME, TASK_CLASS,
properties, triggerInfo);
taskManager.registerTask(taskInfo);
@ -130,7 +132,7 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
Map<String, String> properties = new HashMap<>();
properties.put(TENANT_ID, String.valueOf(tenantId));
TaskInfo taskInfo = new TaskInfo(TASK_NAME, deviceTaskManager.getTaskImplementedClazz(), properties,
TaskInfo taskInfo = new TaskInfo(TASK_NAME, TASK_CLASS, properties,
triggerInfo);
taskManager.registerTask(taskInfo);

@ -17,12 +17,11 @@
*/
package org.wso2.carbon.device.mgt.core;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.TaskOperation;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
@ -42,6 +41,11 @@ public class TestDeviceManagementService implements DeviceManagementService {
return providerType;
}
@Override
public List<TaskOperation> getTasksForPlatform(){
return null;
}
@Override
public void init() throws DeviceManagementException {

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-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.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -27,7 +27,7 @@
}
},
"sso": {
"enabled": false,
"enabled": true,
"issuer" : "devicemgt",
"appName" : "devicemgt",
"identityProviderUrl" : "https://localhost:9443/samlsso",

@ -11,6 +11,7 @@
"dashboardServerURL" : "%https.ip%",
"androidEnrollmentDir": "/android-web-agent/enrollment",
"windowsEnrollmentDir": "/windows-web-agent/enrollment",
"iOSEnrollmentDir": "/ios-web-agent/enrollment",
"iOSConfigRoot" : "%https.ip%/ios-enrollment/",
"iOSAPIRoot" : "%https.ip%/ios/",
"adminService": "%https.ip%",

@ -79,4 +79,30 @@ var groupModule = {};
);
};
groupModule.getGroups = function () {
var permissions = userModule.getUIPermissions();
if (permissions.LIST_ALL_GROUPS) {
endPoint = deviceServiceEndpoint + "/admin/groups";
} else if (permissions.LIST_GROUPS) {
endPoint = deviceServiceEndpoint + "/groups";
} else {
log.error("Access denied for user: " + carbonUser.username);
return -1;
}
return serviceInvokers.XMLHttp.get(
endPoint, function (responsePayload) {
var data = JSON.parse(responsePayload.responseText);
if(data) {
return data.deviceGroups;
} else {
return [];
}
},
function (responsePayload) {
log.error(responsePayload);
return -1;
}
);
};
}(groupModule));

@ -48,6 +48,7 @@ var operationModule = function () {
feature["operation"] = features[i].code;
feature["name"] = features[i].name;
feature["description"] = features[i].description;
feature["contentType"] = features[i].contentType;
feature["deviceType"] = deviceType;
feature["params"] = [];
var metaData = features[i].metadataEntries;
@ -81,6 +82,10 @@ var operationModule = function () {
var iconPath = utility.getOperationIcon(deviceType, iconIdentifier);
operations[op]["icon"] = iconPath;
}
var formParams = features[iconIdentifier].formParams;
if (formParams) {
operations[op]["uiParams"] = formParams;
}
}
}
return operations;

@ -500,10 +500,11 @@ var userModule = function () {
publicMethods.getUIPermissions = function () {
var permissions = {};
if (publicMethods.isAuthorized("/permission/admin/device-mgt/devices/list")) {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/devices/any-device")) {
permissions["LIST_DEVICES"] = true;
permissions["LIST_OWN_DEVICES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/devices/list")) {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/devices/owning-device")) {
permissions["LIST_OWN_DEVICES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/groups/view")) {
@ -524,10 +525,10 @@ var userModule = function () {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/policies/list")) {
permissions["LIST_POLICIES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/devices/add")) {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/devices/enroll")) {
permissions["ADD_DEVICE"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/groups/add")) {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/groups/add")) {
permissions["ADD_GROUP"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/users/add")) {
@ -542,9 +543,6 @@ var userModule = function () {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/groups/devices/view")) {
permissions["VIEW_GROUP_DEVICES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/groups/roles/create")) {
permissions["CREATE_GROUP_ROLES"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/groups/roles/view")) {
permissions["VIEW_GROUP_ROLES"] = true;
}

@ -60,6 +60,8 @@ var WEB_SERVICE_ADDRESSING_VERSION = 1.0;
var TOKEN_PAIR = "tokenPair";
var ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS = "encodedTenantBasedClientAppCredentials";
var CONTENT_TYPE_IDENTIFIER = "Content-Type";
var ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS = "encodedTenantBasedWebSocketClientCredentials";
var CONTENT_DISPOSITION_IDENTIFIER = "Content-Disposition";
var APPLICATION_JSON = "application/json";
var APPLICATION_ZIP = "application/zip";
@ -76,4 +78,6 @@ var HTTP_CONFLICT = 409;
var HTTP_CREATED = 201;
var CACHED_CREDENTIALS = "tenantBasedCredentials";
var CACHED_CREDENTIALS_FOR_WEBSOCKET_APP = "tenantBasedWebSocketClientCredentials";
var ALLOWED_SCOPES = "scopes";

@ -29,7 +29,9 @@ var carbonServer = new carbonModule.server.Server({
application.put("carbonServer", carbonServer);
var permissions = {
"/permission/admin/device-mgt/devices": ["ui.execute"],
"/permission/admin/device-mgt/devices/enroll": ["ui.execute"],
"/permission/admin/device-mgt/devices/disenroll": ["ui.execute"],
"/permission/admin/device-mgt/devices/owning-device": ["ui.execute"],
"/permission/admin/device-mgt/groups": ["ui.execute"],
"/permission/admin/device-mgt/notifications": ["ui.execute"],
"/permission/admin/device-mgt/policies": ["ui.execute"],

@ -138,6 +138,63 @@ var utils = function () {
}
};
publicMethods["getTenantBasedWebSocketClientAppCredentials"] = function (username) {
if (!username) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
"based client app credentials. No username " +
"as input - getTenantBasedWebSocketClientAppCredentials(x)");
return null;
} else {
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
var tenantDomain = carbon.server.tenantDomain({username: username});
if (!tenantDomain) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
"based client application credentials. Unable to obtain a valid tenant domain for provided " +
"username - getTenantBasedWebSocketClientAppCredentials(x, y)");
return null;
} else {
var cachedBasedWebsocketClientAppCredentials = privateMethods.
getCachedBasedWebSocketClientAppCredentials(tenantDomain);
if (cachedBasedWebsocketClientAppCredentials) {
return cachedBasedWebsocketClientAppCredentials;
} else {
var adminUsername = deviceMgtProps["adminUser"];
var adminUserTenantId = deviceMgtProps["adminUserTenantId"];
//claims required for jwtAuthenticator.
var claims = {"http://wso2.org/claims/enduserTenantId": adminUserTenantId,
"http://wso2.org/claims/enduser": adminUsername};
var jwtToken = publicMethods.getJwtToken(adminUsername, claims);
// register a tenant based app at API Manager
var applicationName = "websocket_webapp_" + tenantDomain;
var requestURL = (deviceMgtProps["oauthProvider"]["appRegistration"]
["apiManagerClientAppRegistrationServiceURL"]).replace("/tenants","");
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("X-JWT-Assertion", "" + jwtToken);
xhr.send(stringify({applicationName:applicationName, tags:["device_management"],
isAllowedToAllDomains:false, isMappingAnExistingOAuthApp:false, validityPeriod: 3600}));
if (xhr["status"] == 201 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
var tenantTenantBasedWebsocketClientAppCredentials = {};
tenantTenantBasedWebsocketClientAppCredentials["clientId"] = responsePayload["client_id"];
tenantTenantBasedWebsocketClientAppCredentials["clientSecret"] =
responsePayload["client_secret"];
privateMethods.setCachedBasedWebSocketClientAppCredentials(tenantDomain,
tenantTenantBasedWebsocketClientAppCredentials);
return tenantTenantBasedWebsocketClientAppCredentials;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
"based client application credentials from API " +
"Manager - getTenantBasedWebSocketClientAppCredentials(x, y)");
return null;
}
}
}
}
};
privateMethods["setCachedTenantBasedClientAppCredentials"] = function (tenantDomain, clientAppCredentials) {
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS"]);
if (!cachedTenantBasedClientAppCredentialsMap) {
@ -159,7 +216,32 @@ var utils = function () {
}
};
publicMethods["getTokenPairAndScopesByPasswordGrantType"] = function (username, password, encodedClientAppCredentials, scopes) {
privateMethods["getCachedBasedWebSocketClientAppCredentials"] = function (tenantDomain) {
var cachedBasedWebSocketClientAppCredentialsMap
= application.get(constants["CACHED_CREDENTIALS_FOR_WEBSOCKET_APP"]);
if (!cachedBasedWebSocketClientAppCredentialsMap ||
!cachedBasedWebSocketClientAppCredentialsMap[tenantDomain]) {
return null;
} else {
return cachedBasedWebSocketClientAppCredentialsMap[tenantDomain];
}
};
privateMethods["setCachedBasedWebSocketClientAppCredentials"] = function (tenantDomain, clientAppCredentials) {
var cachedBasedWebSocketClientAppCredentialsMap
= application.get(constants["CACHED_CREDENTIALS_FOR_WEBSOCKET_APP"]);
if (!cachedBasedWebSocketClientAppCredentialsMap) {
cachedBasedWebSocketClientAppCredentialsMap = {};
cachedBasedWebSocketClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
application.put(constants["CACHED_CREDENTIALS_FOR_WEBSOCKET_APP"]
, cachedBasedWebSocketClientAppCredentialsMap);
} else if (!cachedBasedWebSocketClientAppCredentialsMap[tenantDomain]) {
cachedBasedWebSocketClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
}
};
publicMethods["getTokenPairAndScopesByPasswordGrantType"] = function (username, password
, encodedClientAppCredentials, scopes) {
if (!username || !password || !encodedClientAppCredentials || !scopes) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by password " +
"grant type. No username, password, encoded client app credentials or scopes are " +

@ -39,6 +39,7 @@ var handlers = function () {
"as input - setupTokenPairByPasswordGrantType(x, y)");
} else {
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
privateMethods.setUpEncodedTenantBasedWebSocketClientAppCredentials(username);
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
if (!encodedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
@ -81,6 +82,7 @@ var handlers = function () {
"as input - setupTokenPairByPasswordGrantType(x, y)");
} else {
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
privateMethods.setUpEncodedTenantBasedWebSocketClientAppCredentials(username);
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
if (!encodedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair " +
@ -168,5 +170,44 @@ var handlers = function () {
}
};
privateMethods["setUpEncodedTenantBasedWebSocketClientAppCredentials"] = function (username) {
if (!username) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
"client credentials to session context. No username of logged in user is found as " +
"input - setUpEncodedTenantBasedWebSocketClientAppCredentials(x)");
} else {
if (devicemgtProps["apimgt-gateway"]) {
var tenantBasedWebSocketClientAppCredentials
= tokenUtil.getTenantBasedWebSocketClientAppCredentials(username);
if (!tenantBasedWebSocketClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant " +
"based client credentials to session context as the server is unable " +
"to obtain such credentials - setUpEncodedTenantBasedWebSocketClientAppCredentials(x)");
} else {
var encodedTenantBasedWebSocketClientAppCredentials =
tokenUtil.encode(tenantBasedWebSocketClientAppCredentials["clientId"] + ":" +
tenantBasedWebSocketClientAppCredentials["clientSecret"]);
// setting up encoded tenant based client credentials to session context.
session.put(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"],
encodedTenantBasedWebSocketClientAppCredentials);
}
} else {
var dynamicClientAppCredentials = tokenUtil.getDynamicClientAppCredentials();
if (!dynamicClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
"client credentials to session context as the server is unable to obtain " +
"dynamic client credentials - setUpEncodedTenantBasedWebSocketClientAppCredentials(x)");
}
var encodedTenantBasedWebSocketClientAppCredentials =
tokenUtil.encode(dynamicClientAppCredentials["clientId"] + ":" +
dynamicClientAppCredentials["clientSecret"]);
// setting up encoded tenant based client credentials to session context.
session.put(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"],
encodedTenantBasedWebSocketClientAppCredentials);
}
}
};
return publicMethods;
}();

@ -6,9 +6,9 @@
<i class="square-element text fw fw-document"></i>
</div>
</td>
<td class="fade-edge remove-padding-top" data-search="{{serialNumber}}" data-display="{{serialNumber}}"><i
<td class="remove-padding-top" data-search="{{serialNumber}}" data-display="{{serialNumber}}"><i
class="fw-mobile"></i> {{serialNumber}}</td>
<td class="fade-edge remove-padding-top" data-search="{{subject}}" data-display="{{subject}}"><i
<td class="remove-padding-top" data-search="{{subject}}" data-display="{{subject}}"><i
class="fw-policy"></i> {{subject}}</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap">
{{#unequal adminUser serialNumber }}

@ -12,21 +12,21 @@
<i class="square-element text fw fw-mobile"></i>
</div>
</td>
<td class="fade-edge" data-search="{{properties.DEVICE_MODEL}},{{properties.VENDOR}}" data-display="{{properties.DEVICE_MODEL}}">
<td data-search="{{properties.DEVICE_MODEL}},{{properties.VENDOR}}" data-display="{{properties.DEVICE_MODEL}}">
<h4>Device {{name}}</h4>
{{#if properties.DEVICE_MODEL}}
<div>({{properties.VENDOR}} - {{properties.DEVICE_MODEL}})</div>
{{/if}}
</td>
<td class="fade-edge remove-padding-top" data-search="{{enrolmentInfo.owner}}" data-display="{{enrolmentInfo.owner}}" data-grid-label="Owner">{{enrolmentInfo.owner}}</td>
<td class="fade-edge remove-padding-top" data-search="{{enrolmentInfo.status}}" data-display="{{enrolmentInfo.status}}" data-grid-label="Status">
<td class="remove-padding-top" data-search="{{enrolmentInfo.owner}}" data-display="{{enrolmentInfo.owner}}" data-grid-label="Owner">{{enrolmentInfo.owner}}</td>
<td class="remove-padding-top" data-search="{{enrolmentInfo.status}}" data-display="{{enrolmentInfo.status}}" data-grid-label="Status">
{{#equal enrolmentInfo.status "ACTIVE"}}<span><i class="fw fw-ok icon-success"></i> Active</span>{{/equal}}
{{#equal enrolmentInfo.status "INACTIVE"}}<span><i class="fw fw-warning icon-warning"></i> Inactive</span>{{/equal}}
{{#equal enrolmentInfo.status "BLOCKED"}}<span><i class="fw fw-remove icon-danger"></i> Blocked</span>{{/equal}}
{{#equal enrolmentInfo.status "REMOVED"}}<span><i class="fw fw-delete icon-danger"></i> Removed</span>{{/equal}}
</td>
<td class="fade-edge remove-padding-top" data-search="{{type}}" data-display="{{type}}" data-grid-label="Type">{{type}}</td>
<td class="fade-edge remove-padding-top" data-search="{{enrolmentInfo.ownership}}" data-display="{{enrolmentInfo.ownership}}" data-grid-label="Ownership">{{enrolmentInfo.ownership}}</td>
<td class="remove-padding-top" data-search="{{type}}" data-display="{{type}}" data-grid-label="Type">{{type}}</td>
<td class="remove-padding-top" data-search="{{enrolmentInfo.ownership}}" data-display="{{enrolmentInfo.ownership}}" data-grid-label="Ownership">{{enrolmentInfo.ownership}}</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap">
<!--{{#equal type "TemperatureController"}}
{{#equal status "INACTIVE"}}

@ -73,11 +73,6 @@
{{/zone}}
{{#zone "content"}}
<div class="row wr-device-board" style="margin-top: -10px;">
<div class="col-lg-12 wr-secondary-bar">
<span class="page-sub-title">{{title}}</span>
</div>
</div>
<div class="wr-device-list row">
<div class="wr-hidden-operations wr-advance-operations"></div>
<div class="col-md-12 wr-page-content">
@ -157,34 +152,41 @@
{{else}}
<div id="ast-container" class="ast-container list-view">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any device
<h3 class="text-muted">
<i class="fw fw-devices fw-3x"></i>
</h3>
<h3 class="text-muted">
You don't have any device
{{#if groupName}}
assigned to this group
assigned to this group
{{else}}
registered
enrolled
{{/if}}
at the moment.</h2>
<br />
<p class="text-center">
at the moment.
</h3>
<h3>
{{#if groupName}}
<a href="{{@app.context}}/devices" class="wr-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/devices" class="btn-operations btn-default">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Assign from My Devices
</a>
{{else}}
<a href="{{@app.context}}/device/enroll" class="wr-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Enroll New Device
</a>
{{#if permissions.enroll}}
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/device/enroll" class="btn-operations btn-default">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Enroll New Device
</a>
{{/if}}
{{/if}}
</p>
</h3>
</div>
</div>
{{/if}}

@ -265,7 +265,7 @@ function loadDevices(searchType, searchParam) {
{
targets: 1,
data: 'name',
class: 'fade-edge',
class: '',
render: function (name, type, row, meta) {
var model = getPropertyValue(row.properties, 'DEVICE_MODEL');
var vendor = getPropertyValue(row.properties, 'VENDOR');
@ -279,12 +279,12 @@ function loadDevices(searchType, searchParam) {
{
targets: 2,
data: 'user',
class: 'fade-edge remove-padding-top',
class: 'remove-padding-top',
},
{
targets: 3,
data: 'status',
class: 'fade-edge remove-padding-top',
class: 'remove-padding-top',
render: function (status, type, row, meta) {
var html;
switch (status) {
@ -307,7 +307,7 @@ function loadDevices(searchType, searchParam) {
{
targets: 4,
data: 'deviceType',
class: 'fade-edge remove-padding-top',
class: 'remove-padding-top',
render: function (status, type, row, meta) {
return getDeviceTypeLabel(row.deviceType);
}
@ -315,7 +315,7 @@ function loadDevices(searchType, searchParam) {
{
targets: 5,
data: 'ownership',
class: 'fade-edge remove-padding-top',
class: 'remove-padding-top',
render: function (status, type, row, meta) {
if (getDeviceTypeCategory(row.deviceType) == 'mobile') {
return row.ownership;

@ -36,9 +36,11 @@
<div class="form-login-box">
<label class="wr-input-label">Group Name</label>
<div class="wr-input-control">
<div class="form-group wr-input-control">
<input type="text right" id="name" placeholder="Group Name" data-regex="{{groupNameJSRegEx}}"
data-errormsg="{{groupNameRegExViolationErrorMsg}}">
data-errormsg="{{groupNameRegExViolationErrorMsg}}" class="form-control">
<span class="groupNameError hidden glyphicon glyphicon-remove form-control-feedback"></span>
<label class="error groupNameEmpty hidden" for="summary"></label>
</div>
<label class="wr-input-label">Description</label>

@ -35,12 +35,10 @@ $(function () {
var description = $("input#description").val();
if (!name) {
$('.wr-validation-summary strong').text("Group Name is a required field. It cannot be empty.");
$('.wr-validation-summary').removeClass("hidden");
triggerError($("input#name"),"Group Name is a required field. It cannot be empty.");
return false;
} else if (!inputIsValid($("input#name").data("regex"), name)) {
$('.wr-validation-summary strong').text($("input#name").data("errormsg"));
$('.wr-validation-summary').removeClass("hidden");
triggerError($("input#name"),$("input#name").data("errormsg"));
return false;
} else {
var group = {"name": name, "description": description};
@ -69,6 +67,61 @@ $(function () {
});
});
/**
* @param el
* @param errorMsg
*
* Triggers validation error for provided element.
* Note : the basic jQuery validation elements should be present in the markup
*
*/
function triggerError(el,errorMsg){
var parent = el.parents('.form-group'),
errorSpan = parent.find('span'),
errorMsgContainer = parent.find('label');
errorSpan.on('click',function(event){
event.stopPropagation();
removeErrorStyling($(this));
el.unbind('.errorspace');
});
el.bind('focusin.errorspace',function(){
removeErrorStyling($(this))
}).bind('focusout.errorspace',function(){
addErrorStyling($(this));
}).bind('keypress.errorspace',function(){
$(this).unbind('.errorspace');
removeErrorStyling($(this));
});
errorMsgContainer.text(errorMsg);
parent.addClass('has-error has-feedback');
errorSpan.removeClass('hidden');
errorMsgContainer.removeClass('hidden');
function removeErrorStyling(el){
var parent = el.parents('.form-group'),
errorSpan = parent.find('span'),
errorMsgContainer = parent.find('label');
parent.removeClass('has-error has-feedback');
errorSpan.addClass('hidden');
errorMsgContainer.addClass('hidden');
}
function addErrorStyling(el){
var parent = el.parents('.form-group'),
errorSpan = parent.find('span'),
errorMsgContainer = parent.find('label');
parent.addClass('has-error has-feedback');
errorSpan.removeClass('hidden');
errorMsgContainer.removeClass('hidden');
}
}
function displayErrors(message) {
$('#error-msg').html(message.responseText);
modalDialog.header('Unexpected error occurred!');

@ -79,18 +79,21 @@
{{else}}
<div id="ast-container" class="ast-container list-view">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any group registered at the moment.</h2>
<br />
<h3 class="text-muted">
<i class="fw fw-grouping fw-3x"></i>
</h3>
<h3 class="text-muted">You don't have any group registered at the moment</h3>
{{#if permissions.ADD_GROUP}}
<p class="text-center">
<a href="{{@app.context}}/group/add" class="wr-btn">
<h3>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/group/add" class="btn-operations btn-default">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add New Group
</a>
</p>
</h3>
{{/if}}
</div>
</div>

@ -93,7 +93,7 @@ function loadGroups() {
var currentUser = groupListing.data("currentUser");
var serviceURL;
if ($.hasPermission("LIST_ALL_GROUPS")) {
serviceURL = "/api/device-mgt/v1.0/groups";
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;
@ -113,8 +113,7 @@ function loadGroups() {
groupId: data.deviceGroups[index].id,
name: data.deviceGroups[index].name,
description: data.deviceGroups[index].description,
owner: data.deviceGroups[index].owner,
dateOfCreation: data.deviceGroups[index].dateOfCreation
owner: data.deviceGroups[index].owner
})
});
var json = {
@ -136,24 +135,24 @@ function loadGroups() {
{
targets: 1,
data: 'name',
class: 'fade-edge'
class: ''
},
{
targets: 2,
data: 'owner',
class: 'fade-edge remove-padding-top',
class: 'remove-padding-top',
},
{
targets: 3,
data: 'description',
class: 'fade-edge remove-padding-top',
class: 'remove-padding-top',
},
{
targets: 4,
data: 'id',
class: 'text-right content-fill text-left-on-grid-view no-wrap',
render: function (id, type, row, meta) {
var html;
var html = '';
if ($.hasPermission("VIEW_GROUP_DEVICES")) {
html = '<a href="devices?groupId=' + row.groupId + '&groupName=' + row.name
+ '" data-click-event="remove-form" class="btn padding-reduce-on-grid-view">' +
@ -166,46 +165,39 @@ function loadGroups() {
'<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></a>';
} else {
html = '';
}
if ($.hasPermission("SHARE_GROUP")) {
html +=
'<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view share-group-link" data-group-id="'
+ row.groupId + '" ' +
'data-group-owner="' + row.owner
+ '"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i><i class="fw fw-share fw-stack-1x"></i></span>'
+
'<span class="hidden-xs hidden-on-grid-view">Share</span></a>';
} else {
html += '';
}
if ($.hasPermission("UPDATE_GROUP")) {
html +=
'<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view edit-group-link" data-group-name="'
+ row.name + '" ' +
'data-group-owner="' + row.owner + '" data-group-description="' + row.description
+ '" data-group-id="' + row.groupId
+ '"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i>' +
'<i class="fw fw-edit fw-stack-1x"></i></span><span class="hidden-xs hidden-on-grid-view">Edit</span></a>';
} else {
html += '';
}
if ($.hasPermission("REMOVE_GROUP")) {
html +=
'<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view remove-group-link" data-group-id="'
+ row.groupId + '" ' +
'data-group-owner="' + row.owner
+ '"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i><i class="fw fw-delete fw-stack-1x"></i>'
+
'</span><span class="hidden-xs hidden-on-grid-view">Delete</span></a>';
} else {
html += '';
if (row.owner != "wso2.system.user") {
if ($.hasPermission("SHARE_GROUP")) {
html +=
'<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view share-group-link" data-group-id="'
+ row.groupId + '" ' +
'data-group-owner="' + row.owner
+ '"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i><i class="fw fw-share fw-stack-1x"></i></span>'
+
'<span class="hidden-xs hidden-on-grid-view">Share</span></a>';
}
if ($.hasPermission("UPDATE_GROUP")) {
html +=
'<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view edit-group-link" data-group-name="'
+ row.name + '" ' +
'data-group-owner="' + row.owner + '" data-group-description="' + row.description
+ '" data-group-id="' + row.groupId
+ '"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i>' +
'<i class="fw fw-edit fw-stack-1x"></i></span><span class="hidden-xs hidden-on-grid-view">Edit</span></a>';
}
if ($.hasPermission("REMOVE_GROUP")) {
html +=
'<a href="#" data-click-event="remove-form" class="btn padding-reduce-on-grid-view remove-group-link" data-group-id="'
+ row.groupId + '" ' +
'data-group-owner="' + row.owner
+ '"><span class="fw-stack"><i class="fw fw-ring fw-stack-2x"></i><i class="fw fw-delete fw-stack-1x"></i>'
+
'</span><span class="hidden-xs hidden-on-grid-view">Delete</span></a>';
}
}
return html;
}
}
];
var fnCreatedRow = function (row, data) {

@ -34,6 +34,7 @@
</a>
</li>
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policies">
Policies
</a>
@ -41,18 +42,24 @@
{{/zone}}
{{#zone "navbarActions"}}
{{#if managePermitted}}
<li>
<a href="{{@app.context}}/policy/add" class="cu-btn">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Add Policy
</a>
</li>
{{#if permissions.ADD_ADMIN_POLICY}}
{{#equal noPolicy false}}
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/add" class="cu-btn">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-ring fw-stack-2x"></i>
</span>
Add New Policy
</a>
</li>
{{/equal}}
{{/if}}
{{#if permissions.CHANGE_POLICY_PRIORITY}}
{{#equal noPolicy false}}
<li>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/priority" class="cu-btn">
<span class="icon fw-stack">
<i class="fw fw-throttling-policy fw-stack-1x"></i>
@ -75,44 +82,37 @@
{{/zone}}
{{#zone "content"}}
{{#equal isUpdated true}}
<input type="hidden" id="is-updated" value="UPDATED">
{{/equal}}
{{#equal noPolicy true}}
<div id="ast-container" class="ast-container list-view">
<div class="ctrl-info-panel col-centered text-center wr-login">
<h2>You don't have any policy at the moment.</h2>
<br/>
{{#if managePermitted}}
<p class="text-center">
<a href="{{@app.context}}/policy/add" class="wr-btn">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
<h3 class="text-muted">
<i class="fw fw-policy fw-3x"></i>
</h3>
<h3 class="text-muted">You do not have any device policy at the moment</h3>
{{#if permissions.ADD_ADMIN_POLICY}}
<h3>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/add" class="btn-operations btn-default">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add New Policy
</a>
</p>
</h3>
{{/if}}
</div>
</div>
{{/equal}}
{{#equal noPolicy false}}
{{#equal isUpdated true}}
<input type="hidden" id="is-updated" name="country" value="UPDATED">
{{/equal}}
<div id="loading-content" class="col-centered">
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading policies . . .
<br>
</div>
<div id="policy-listing-status" class="raw hidden">
<ul style="list-style-type: none;">
<li class="message message-info">
<h4>
<i class="icon fw fw-info"></i>
<a id="policy-listing-status-msg">{{policyListingStatusMsg}}</a>
</h4>
</li>
</ul>
</div>
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view hidden"
id="policy-grid">
<thead>
@ -141,10 +141,9 @@
<tr class="bulk-action-row">
<th colspan="9">
<ul class="tiles">
{{#if managePermitted}}
{{#if removePermitted}}
<li class="square">
<a href="#" data-click-event="remove-form"
class="btn square-element policy-remove-link"
<a href="#" data-click-event="remove-form" class="btn square-element policy-remove-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -155,8 +154,7 @@
</li>
{{/if}}
<li class="square">
<a href="#" data-click-event="remove-form"
class="btn square-element policy-publish-link"
<a href="#" data-click-event="remove-form" class="btn square-element policy-publish-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -166,8 +164,7 @@
</a>
</li>
<li class="square">
<a href="#" data-click-event="remove-form"
class="btn square-element policy-unpublish-link"
<a href="#" data-click-event="remove-form" class="btn square-element policy-unpublish-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
@ -185,56 +182,73 @@
{{#each policyListToView}}
<tr data-type="selectable" data-id="{{id}}" data-status="{{status}}">
<td class="remove-padding icon-only content-fill viewEnabledIcon"
data-url="{{@app.context}}/policy/view?id={{id}}&type={{platform}}"
data-id="{{id}}">
<div class="thumbnail icon">
<img src="{{icon}}"/>
data-url="{{@app.context}}/policy/view?id={{id}}" data-id="{{id}}">
<div class="thumbnail icon" style="padding-top: 30px; padding-bottom: 30px;">
<i class="fw fw-{{deviceTypeIcon}}" style="font-size: 59px"></i>
</div>
</td>
<td class="fade-edge" data-search="{{name}}" data-display="{{name}}">
<td
data-search="{{name}}"
data-display="{{name}}">
<h4>{{name}}</h4>
<div>({{platform}})</div>
{{#equal status "Active/Updated"}}
<i class="fw fw-warning icon-success"></i> Active/Updated</span>
<span><i class="fw fw-warning icon-success"></i> Active/Updated</span>
{{/equal}}
{{#equal status "Active"}}
<i class="fw fw-ok icon-success"></i> Active</span>
<span><i class="fw fw-ok icon-success"></i> Active</span>
{{/equal}}
{{#equal status "Inactive/Updated"}}
<i class="fw fw-warning icon-warning"></i> Inactive/Updated</span>
<span><i class="fw fw-warning icon-warning"></i> Inactive/Updated</span>
{{/equal}}
{{#equal status "Inactive"}}
<i class="fw fw-error icon-danger"></i> Inactive</span>
<span><i class="fw fw-error icon-danger"></i> Inactive</span>
{{/equal}}
</td>
<td class="fade-edge remove-padding-top" data-search="{{platform}}"
data-display="{{platform}}"></td>
<td class="fade-edge remove-padding-top" data-search="{{ownershipType}}"
<td class="remove-padding-top"
data-search="{{platform}}"
data-display="{{platform}}">
</td>
<td class="remove-padding-top"
data-search="{{ownershipType}}"
data-display="{{ownershipType}}"
data-grid-label="Ownership">{{ownershipType}}</td>
<td id="policy-roles" class="fade-edge remove-padding-top" data-search="{{roles}}"
data-grid-label="Ownership">
{{ownershipType}}
</td>
<td id="policy-roles" class="remove-padding-top"
data-search="{{roles}}"
data-display="{{roles}}"
data-grid-label="Role(s)">{{roles}}</td>
<td id="policy-users" class="fade-edge remove-padding-top" data-search="{{users}}"
data-display="{{users}}" data-grid-label="User(s)">{{users}}</td>
<td class="fade-edge remove-padding-top" data-search="{{compliance}}"
data-display="{{compliance}}" data-grid-label="Compliance">{{compliance}}</td>
<td id="policy-status" class="fade-edge remove-padding-top" data-search="{{status}}"
data-grid-label="Role(s)">
{{roles}}
</td>
<td id="policy-users" class="remove-padding-top"
data-search="{{users}}"
data-display="{{users}}"
data-grid-label="User(s)">
{{users}}
</td>
<td class="remove-padding-top"
data-search="{{compliance}}"
data-display="{{compliance}}"
data-grid-label="Compliance">
{{compliance}}
</td>
<td id="policy-status" class="remove-padding-top"
data-search="{{status}}"
data-display="{{status}}">
</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap">
<a href="{{@app.context}}/policy/edit?id={{id}}&type={{platform}}"
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/edit?id={{id}}"
data-id="{{id}}"
data-click-event="remove-form"
class="btn padding-reduce-on-grid-view policy-update-link">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-edit fw-stack-1x"></i>
</span>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-edit fw-stack-1x"></i>
</span>
<span class="hidden-xs hidden-on-grid-view">Re-Configure</span>
</a>
</td>
</tr>
{{/each}}

@ -6,12 +6,12 @@
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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
* "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.
*/
@ -37,27 +37,23 @@ function onRequest(context) {
var policyCount = policyListToView.length;
if (policyCount == 0) {
page["policyListingStatusMsg"] = "No policy is available to be displayed.";
page["saveNewPrioritiesButtonEnabled"] = false;
page["noPolicy"] = true;
} else if (policyCount == 1) {
page["saveNewPrioritiesButtonEnabled"] = false;
page["noPolicy"] = false;
page["isUpdated"] = response["updated"];
} else {
page["saveNewPrioritiesButtonEnabled"] = true;
page["noPolicy"] = false;
page["isUpdated"] = response["updated"];
}
} else {
// here, response["status"] == "error"
page["policyListToView"] = [];
page["policyListingStatusMsg"] = "An unexpected error occurred @ backend. Please try again later.";
page["saveNewPrioritiesButtonEnabled"] = false;
page["policyListingStatusMsg"] = "An unexpected error occurred. Please try again later.";
page["noPolicy"] = true;
}
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/manage")) {
page.managePermitted = true;
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/remove")) {
page["removePermitted"] = true;
}
if (userModule.isAuthorized("/permission/admin/device-mgt/policies/update")) {
page["editPermitted"] = true;
}
page.permissions = userModule.getUIPermissions();
return page;
}
}

@ -1,30 +1,30 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2015-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
* 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
* "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.
*/
/* sorting function */
var sortUpdateBtn = "#sortUpdateBtn";
var sortedIDs;
var dataTableSelection = '.DTTT_selected';
// var sortedIDs;
// var dataTableSelection = ".DTTT_selected";
var settings = {
"sorting": false
};
$('#policy-grid').datatables_extended(settings);
$(".icon .text").res_text(0.2);
// $(".icon .text").res_text(0.2);
var saveNewPrioritiesButton = "#save-new-priorities-button";
var saveNewPrioritiesButtonEnabled = Boolean($(saveNewPrioritiesButton).data("enabled"));
@ -41,25 +41,6 @@ function InitiateViewOption() {
$(location).attr('href', $(this).data("url"));
}
var addSortableIndexNumbers = function () {
$(".wr-sortable .list-group-item").not(".ui-sortable-placeholder").each(function (i) {
$(".wr-sort-index", this).html(i + 1);
});
};
var sortElements = function () {
addSortableIndexNumbers();
var sortableElem = ".wr-sortable";
$(sortableElem).sortable({
beforeStop: function () {
sortedIDs = $(this).sortable("toArray");
addSortableIndexNumbers();
$(sortUpdateBtn).prop("disabled", false);
}
});
$(sortableElem).disableSelection();
};
/**
* Modal related stuff are as follows.
*/
@ -129,31 +110,29 @@ function getSelectedPolicies() {
}
$(document).ready(function () {
sortElements();
$("#loading-content").remove();
var policyRoles = $("#policy-roles").text();
var policyUsers = $("#policy-users").text();
/**
* ********************************************
* Click functions related to Policy Listing
* ********************************************
*/
if (!policyRoles) {
$("#policy-roles").hide();
}
if (!policyUsers) {
$("#policy-users").hide();
}
// [1] logic for running apply-changes-for-devices use-case
if ($("#policy-listing-status-msg").text()) {
$("#policy-listing-status").removeClass("hidden");
}
var applyChangesButtonId = "#appbar-btn-apply-changes";
// Click functions related to Policy Listing
var isUpdated = $('#is-updated').val();
var isUpdated = $("#is-updated").val();
if (!isUpdated) {
$('#appbar-btn-apply-changes').addClass('hidden');
// if no updated policies found, hide button from app bar
$(applyChangesButtonId).addClass("hidden");
} else {
// if updated policies found, show button from app bar
$(applyChangesButtonId).removeClass("hidden");
}
$("#appbar-btn-apply-changes").click(function () {
var applyPolicyChangesAPI = "/devicemgt_admin/policies/apply-changes";
// click-event function for applyChangesButton
$(applyChangesButtonId).click(function () {
var serviceURL = "/api/device-mgt/v1.0/policies/apply-changes";
modalDialog.header('Do you really want to apply changes to all policies?');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-yes-link" class="btn-operations">Yes' +
'</a><a href="#" id="change-policy-cancel-link" class="btn-operations btn-default">No</a></div>');
@ -161,20 +140,23 @@ $(document).ready(function () {
$("a#change-policy-yes-link").click(function () {
invokerUtil.put(
applyPolicyChangesAPI,
serviceURL,
null,
// on success
function () {
modalDialog.header('Done. Changes applied successfully.');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#change-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
modalDialog.header('Done. Changes applied successfully.');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#change-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
}
},
// on error
function () {
function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="change-policy-error-link" ' +
'class="btn-operations">Ok</a></div>');
@ -191,61 +173,26 @@ $(document).ready(function () {
});
});
$(sortUpdateBtn).click(function () {
$(sortUpdateBtn).prop("disabled", true);
var newPolicyPriorityList = [];
var policy;
var i;
for (i = 0; i < sortedIDs.length; i++) {
policy = {};
policy.id = parseInt(sortedIDs[i]);
policy.priority = i + 1;
newPolicyPriorityList.push(policy);
}
var updatePolicyAPI = "/devicemgt_admin/policies/priorities";
invokerUtil.put(
updatePolicyAPI,
newPolicyPriorityList,
function () {
modalDialog.header('Done. New Policy priorities were successfully updated.');
modalDialog.footer('<a href="#" id="save-policy-priorities-success-link" class="btn-operations">Ok' +
'</a>');
modalDialog.show();
$("a#save-policy-priorities-success-link").click(function () {
modalDialog.hide();
});
},
function () {
modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.content(html("Message From Server : " + data["statusText"]));
modalDialog.footer('<div class="buttons"><a href="#" id="save-policy-priorities-error-link" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsError();
$("a#save-policy-priorities-error-link").click(function () {
modalDialog.hide();
});
}
);
});
// [2] logic for un-publishing a selected set of Active, Active/Updated policies
$(".policy-unpublish-link").click(function () {
var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates();
if (($.inArray('Inactive/Updated', statusList) > -1) || ($.inArray('Inactive', statusList) > -1)) {
modalDialog.header('Operation cannot be performed !');
modalDialog.content('You cannot select already inactive policies. Please deselect inactive policies and ' +
'try again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a></div>');
if (($.inArray("Inactive/Updated", statusList) > -1) || ($.inArray("Inactive", statusList) > -1)) {
// if policies found in Inactive or Inactive/Updated states with in the selection,
// pop-up an error saying
// "You cannot select already inactive policies. Please deselect inactive policies and try again."
modalDialog.header('Action cannot be performed !');
modalDialog.content('You cannot select already inactive policies to be unpublished. Please deselect ' +
'inactive policies and try again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">Ok</a>' +
'</div>');
modalDialog.showAsAWarning();
} else {
var serviceURL = "/devicemgt_admin/policies/inactivate";
if (policyList == 0) {
modalDialog.header('Operation cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to unpublish.');
var serviceURL = "/api/device-mgt/v1.0/policies/deactivate-policy";
if (policyList.length == 0) {
modalDialog.header('Action cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to un-publish.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsAWarning();
@ -257,22 +204,26 @@ $(document).ready(function () {
modalDialog.show();
}
// on-click function for policy un-publishing "yes" button
$("a#unpublish-policy-yes-link").click(function () {
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success
function () {
modalDialog.header('Done. Selected policy was successfully unpublished.');
modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#unpublish-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
modalDialog.header('Done. Selected policy was successfully unpublished.');
modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#unpublish-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
}
},
// on error
function () {
function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="unpublish-policy-error-link" ' +
'class="btn-operations">Ok</a></div>');
@ -284,30 +235,35 @@ $(document).ready(function () {
);
});
// on-click function for policy un-publishing "cancel" button
$("a#unpublish-policy-cancel-link").click(function () {
modalDialog.hide();
});
}
});
// [3] logic for publishing a selected set of Inactive, Inactive/Updated policies
$(".policy-publish-link").click(function () {
var policyList = getSelectedPolicies();
var statusList = getSelectedPolicyStates();
if (($.inArray('Active/Updated', statusList) > -1) || ($.inArray('Active', statusList) > -1)) {
modalDialog.header('Operation cannot be performed !');
if (($.inArray("Active/Updated", statusList) > -1) || ($.inArray("Active", statusList) > -1)) {
// if policies found in Active or Active/Updated states with in the selection,
// pop-up an error saying
// "You cannot select already active policies. Please deselect active policies and try again."
modalDialog.header('Action cannot be performed !');
modalDialog.content('You cannot select already active policies. Please deselect active policies and try ' +
'again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' +
'Ok</a></div>');
modalDialog.showAsAWarning();
} else {
var serviceURL = "/devicemgt_admin/policies/activate";
if (policyList == 0) {
modalDialog.header('Operation cannot be performed !');
var serviceURL = "/api/device-mgt/v1.0/policies/activate-policy";
if (policyList.length == 0) {
modalDialog.header('Action cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to publish.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' +
'Ok</a></div>');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsAWarning();
} else {
modalDialog.header('Do you really want to publish the selected policy(s)?');
@ -316,23 +272,26 @@ $(document).ready(function () {
'class="btn-operations btn-default">No</a></div>');
modalDialog.show();
}
// on-click function for policy removing "yes" button
$("a#publish-policy-yes-link").click(function () {
invokerUtil.put(
invokerUtil.post(
serviceURL,
policyList,
// on success
function () {
modalDialog.header('Done. Selected policy was successfully published.');
modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#publish-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
modalDialog.header('Done. Selected policy was successfully published.');
modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#publish-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
}
},
// on error
function () {
function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="publish-policy-error-link" ' +
'class="btn-operations">Ok</a></div>');
@ -344,66 +303,64 @@ $(document).ready(function () {
);
});
// on-click function for policy removing "cancel" button
$("a#publish-policy-cancel-link").click(function () {
modalDialog.hide();
});
}
});
// [4] logic for removing a selected set of policies
$(".policy-remove-link").click(function () {
var policyList = getSelectedPolicies();
var deletePolicyAPI = "/devicemgt_admin/policies/bulk-remove";
if (policyList == 0) {
modalDialog.header('Operation cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to remove.');
var statusList = getSelectedPolicyStates();
if (($.inArray("Active/Updated", statusList) > -1) || ($.inArray("Active", statusList) > -1)) {
// if policies found in Active or Active/Updated states with in the selection,
// pop-up an error saying
// "You cannot remove already active policies. Please deselect active policies and try again."
modalDialog.header('Action cannot be performed !');
modalDialog.content('You cannot select already active policies. Please deselect active policies and try ' +
'again.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" class="btn-operations">' +
'Ok</a></div>');
modalDialog.showAsAWarning();
} else {
modalDialog.header('Do you really want to remove the selected policy(s)?');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-yes-link" class=' +
'"btn-operations">Remove</a> <a href="#" id="remove-policy-cancel-link" ' +
'class="btn-operations btn-default">Cancel</a></div>');
modalDialog.show();
}
var serviceURL = "/api/device-mgt/v1.0/policies/remove-policy";
if (policyList.length == 0) {
modalDialog.header('Action cannot be performed !');
modalDialog.content('Please select a policy or a list of policies to remove.');
modalDialog.footer('<div class="buttons"><a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsAWarning();
} else {
modalDialog.header('Do you really want to remove the selected policy(s)?');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-yes-link" class=' +
'"btn-operations">Remove</a> <a href="#" id="remove-policy-cancel-link" ' +
'class="btn-operations btn-default">Cancel</a></div>');
modalDialog.show();
}
$("a#remove-policy-yes-link").click(function () {
invokerUtil.post(
deletePolicyAPI,
policyList,
// on success
function (data) {
data = JSON.parse(data);
if (data.errorMessage) {
modalDialog.header('Cannot Remove Policies.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-devices" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsError();
$("a#remove-policy-error-devices").click(function () {
modalDialog.hide();
});
} else {
modalDialog.header('Done. Selected policy was successfully removed.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#remove-policy-success-link").click(function () {
var thisTable = $(".DTTT_selected").closest('.dataTables_wrapper').find('.dataTable').dataTable();
thisTable.api().rows('.DTTT_selected').remove().draw(false);
modalDialog.hide();
});
}
},
// on error
function (data) {
if (JSON.parse(data.responseText).errorMessage) {
modalDialog.header('Cannot Remove Policies.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-devices" ' +
'class="btn-operations">Ok</a></div>');
modalDialog.showAsError();
$("a#remove-policy-error-devices").click(function () {
modalDialog.hide();
});
} else {
// on-click function for policy removing "yes" button
$("a#remove-policy-yes-link").click(function () {
invokerUtil.post(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
modalDialog.header('Done. Selected policy was successfully removed.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-success-link" ' +
'class="btn-operations">Ok</a></div>');
$("a#remove-policy-success-link").click(function () {
modalDialog.hide();
location.reload();
});
}
},
// on error
function (jqXHR) {
console.log(stringify(jqXHR.data));
modalDialog.header('An unexpected error occurred. Please try again later.');
modalDialog.footer('<div class="buttons"><a href="#" id="remove-policy-error-link" ' +
'class="btn-operations">Ok</a></div>');
@ -412,15 +369,19 @@ $(document).ready(function () {
modalDialog.hide();
});
}
}
);
});
);
});
$("a#remove-policy-cancel-link").click(function () {
modalDialog.hide();
});
// on-click function for policy removing "cancel" button
$("a#remove-policy-cancel-link").click(function () {
modalDialog.hide();
});
}
});
$("#loading-content").remove();
if ($("#policy-listing-status-msg").text()) {
$("#policy-listing-status").removeClass("hidden");
}
$("#policy-grid").removeClass("hidden");
$(".icon .text").res_text(0.2);
});
});

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

@ -128,7 +128,7 @@ function loadRoles() {
"</div>"
},
{
class: "fade-edge",
class: "",
data: "name",
render: function (name, type, row, meta) {
return '<h4>' + name + '</h4>';

@ -5,7 +5,7 @@
<i class="square-element text fw fw-user"></i>
</div>
</td>
<td class="fade-edge remove-padding-top">{{roleName}}</td>
<td class="remove-padding-top">{{roleName}}</td>
<td class="text-right content-fill text-left-on-grid-view no-wrap">
{{#unequal adminRole roleName }}

@ -31,7 +31,7 @@
{{/if}}
<div class="panel-body">
<form id="signInForm" method="POST" action="{{@app.context}}/uuf/login">
<form id="signInForm" method="POST" action="{{loginActionUrl}}">
<div class="form-group">
<label for="username">Username *</label>
<input type="text" name="username" class="form-control" placeholder="Enter your username"
@ -42,6 +42,9 @@
<input type="password" name="password" class="form-control" placeholder="Enter your password"
required="required" />
</div>
{{#if sessionDataKey}}
<input type="hidden" name="sessionDataKey" value="{{sessionDataKey}}" />
{{/if}}
{{#if referer}}
<input type="hidden" name="referer" value="{{referer}}" />
{{/if}}

@ -0,0 +1,28 @@
function onRequest(context) {
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var authModuleConfigs = context.app.conf["authModule"];
var sessionDataKey = request.getParameter("sessionDataKey");
//if sso enabled and sessionDataKey is empty redirect
var ssoConfigs = authModuleConfigs["sso"];
if (ssoConfigs && (ssoConfigs["enabled"].toString() == "true") && !sessionDataKey) {
// SSO is enabled in Auth module.
var redirectUri = context.app.context + "/uuf/login";
var queryString = request.getQueryString();
if (queryString && (queryString.length > 0)) {
redirectUri = redirectUri + "?" + queryString;
}
response.sendRedirect(encodeURI(redirectUri));
exit();
}
var viewModel = {};
var loginActionUrl = context.app.context + "/uuf/login";
if (sessionDataKey) {
loginActionUrl = devicemgtProps["httpsURL"] + "/commonauth";
}
viewModel.sessionDataKey = sessionDataKey;
viewModel.loginActionUrl = loginActionUrl;
return viewModel;
}

@ -1,5 +1,6 @@
{
"version": "1.0.0",
"layout": "uuf.layout.sign-in",
"uri": "/login",
"extends": "uuf.page.sign-in"
"isAnonymous": true
}

@ -304,7 +304,7 @@ function loadUsers() {
}
},
{
class: "fade-edge",
class: "",
data: null,
render: function (data, type, row, meta) {
if (!data.firstname && !data.lastname) {
@ -315,14 +315,14 @@ function loadUsers() {
}
},
{
class: "fade-edge remove-padding-top",
class: "remove-padding-top",
data: 'filter',
render: function (filter, type, row, meta) {
return '<i class="fw-user"></i>' + filter;
}
},
{
class: "fade-edge remove-padding-top",
class: "remove-padding-top",
data: null,
render: function (data, type, row, meta) {
if (!data.emailAddress) {

@ -6,12 +6,12 @@
<i class="square-element text fw fw-user"></i>
</div>
</td>
<td class="fade-edge" data-search="{{firstname}},{{lastname}}" data-display="{{firstname}} {{lastname}}">
<td data-search="{{firstname}},{{lastname}}" data-display="{{firstname}} {{lastname}}">
<h4>{{firstname}} {{lastname}}</h4>
</td>
<td class="fade-edge remove-padding-top" data-search="{{username}}" data-display="{{username}}"><i
<td class="remove-padding-top" data-search="{{username}}" data-display="{{username}}"><i
class="fw-user"></i> {{username}}</td>
<td class="fade-edge remove-padding-top" data-search="{{emailAddress}}" data-display="{{emailAddress}}">
<td class="remove-padding-top" data-search="{{emailAddress}}" data-display="{{emailAddress}}">
<a href="mailto:{{emailAddress}}" class="wr-list-email">
<i class="fw-mail"></i> {{emailAddress}}
</a>

@ -151,22 +151,26 @@ $.fn.datatables_extended = function(settings){
}
function getAdvanceToolBar(){
if(table.hasClass('sorting-enabled')){
return '<ul class="nav nav-pills navbar-right remove-margin" role="tablist">' +
'<li><button data-click-event="toggle-selectable" class="btn btn-default btn-primary select-enable-btn">Select</li>' +
'<li><button data-click-event="toggle-selected" id="dt-select-all" class="btn btn-default btn-primary disabled">Select All</li>' +
'<li><button data-click-event="toggle-list-view" data-view="grid" class="btn btn-default"><i class="fw fw-grid"></i></button></li>' +
'<li><button data-click-event="toggle-list-view" data-view="list" class="btn btn-default"><i class="fw fw-list"></i></button></li>' +
'<li><button class="btn btn-default" data-toggle="dropdown"><i class="fw fw-sort"></i></button>' + dropdownmenu[0].outerHTML + '</li>' +
'</ul>'
if (!table.hasClass('no-toolbar')) {
if (table.hasClass('sorting-enabled')) {
return '<ul class="nav nav-pills navbar-right remove-margin" role="tablist">' +
'<li><button data-click-event="toggle-selectable" class="btn btn-default btn-primary select-enable-btn">Select</li>' +
'<li><button data-click-event="toggle-selected" id="dt-select-all" class="btn btn-default btn-primary disabled">Select All</li>' +
'<li><button data-click-event="toggle-list-view" data-view="grid" class="btn btn-default"><i class="fw fw-grid"></i></button></li>' +
'<li><button data-click-event="toggle-list-view" data-view="list" class="btn btn-default"><i class="fw fw-list"></i></button></li>' +
'<li><button class="btn btn-default" data-toggle="dropdown"><i class="fw fw-sort"></i></button>' + dropdownmenu[0].outerHTML + '</li>' +
'</ul>'
} else {
return '<ul class="nav nav-pills navbar-right remove-margin" role="tablist">' +
'<li><button data-click-event="toggle-selectable" class="btn btn-default btn-primary select-enable-btn">Select</li>' +
'<li><button data-click-event="toggle-selected" id="dt-select-all" class="btn btn-default btn-primary disabled">Select All</li>' +
'<li><button data-click-event="toggle-list-view" data-view="grid" class="btn btn-default"><i class="fw fw-grid"></i></button></li>' +
'<li><button data-click-event="toggle-list-view" data-view="list" class="btn btn-default"><i class="fw fw-list"></i></button></li>' +
'</ul>'
}
}else{
return '<ul class="nav nav-pills navbar-right remove-margin" role="tablist">' +
'<li><button data-click-event="toggle-selectable" class="btn btn-default btn-primary select-enable-btn">Select</li>' +
'<li><button data-click-event="toggle-selected" id="dt-select-all" class="btn btn-default btn-primary disabled">Select All</li>' +
'<li><button data-click-event="toggle-list-view" data-view="grid" class="btn btn-default"><i class="fw fw-grid"></i></button></li>' +
'<li><button data-click-event="toggle-list-view" data-view="list" class="btn btn-default"><i class="fw fw-list"></i></button></li>' +
'</ul>'
};
return '';
}
}

@ -0,0 +1,14 @@
{{#zone "topCss"}}
{{css "css/codemirror.css"}}
{{/zone}}
<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/codemirror.js"}}
{{js "js/sql.js"}}
{{js "js/editor.js"}}
{{/zone}}

@ -0,0 +1,37 @@
/*
* 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: MIME_TYPE_SIDDHI_QL,
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"
}
});
var validatePolicyProfile = function () {
return true;
};

@ -15,38 +15,33 @@
specific language governing permissions and limitations
under the License.
}}
<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">
<span id="device-listing-status-msg"></span>
<table class="table table-striped table-hover list-table no-operations display responsive nowrap data-table grid-view"
id="device-grid">
<table class="table table-striped table-hover list-table no-operations display responsive nowrap data-table grid-view no-toolbar"
id="device-type-grid">
<thead>
<tr class="sort-row">
<th class="no-sort"></th>
<th>By Device Type</th>
<th class="no-sort"></th>
</tr>
<tr class="filter-row filter-box">
<th data-for="By Category" class="select-filter"></th>
<th data-for="By Device Type" class="text-filter"></th>
<th></th>
</tr>
</thead>
<tbody id="ast-container">
</tbody>
</table>
</div>
<br class="c-both"/>
<div id="content-filter-types" style="display: none">
<div class="sort-title">Sort By</div>
<div class="sort-options">
<a href="#">By Device Type<span class="ico-sort-asc"></span></a>
</div>
</div>
{{#if virtualDeviceTypesList}}
<div class="row wr-device-board">
<div class="col-lg-12 wr-secondary-bar">
<span class="page-sub-title">Virtual Devices</span>
<span class="page-sub-title">Virtual Device Types</span>
</div>
</div>
<h3 style="margin-left: 10px;">Don't have a device?</h3>

@ -141,7 +141,7 @@ function loadDevices(searchType, searchParam){
compileTemplate(viewModel, deviceListingSrc);
}
} else {
$('#device-grid').addClass('hidden');
$('#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>' +
@ -167,7 +167,7 @@ function compileTemplate(viewModel, templateSrc){
$("#ast-container").html($("#ast-container").html() + template(viewModel));
compiledDeviceTypesCount++;
if(deviceTypeCount == compiledDeviceTypesCount){
$('#device-grid').datatables_extended({"bFilter": true, "order": [[ 1, "asc" ]]});
$('#device-type-grid').datatables_extended({"bFilter": false, "order": [[ 1, "asc" ]]});
}
});
}
@ -194,7 +194,7 @@ function openCollapsedNav(){
*/
$(document).ready(function () {
loadDevices();
//$('#device-grid').datatables_extended();
//$('#device-type-grid').datatables_extended();
/* Adding selected class for selected devices */
$(deviceCheckbox).each(function () {

@ -20,6 +20,7 @@
var deviceId = $(".device-id");
var deviceIdentifier = deviceId.data("deviceid");
var deviceType = deviceId.data("type");
var deviceOwner = deviceId.data("owner");
$(document).ready(function () {
$(".panel-body").removeClass("hidden");
@ -45,7 +46,7 @@
});
});
function loadOperationsLog(update) {
var operationsLogTable = "#operations-log-table";
if (update) {
@ -54,76 +55,78 @@
return;
}
operationTable = $(operationsLogTable).datatables_extended({
serverSide: true,
processing: false,
searching: false,
ordering: false,
pageLength : 10,
order: [],
ajax: {
url: context + "/api/operation/paginate",
data: {deviceId : deviceIdentifier, deviceType: deviceType},
dataSrc: function (json) {
$("#operations-spinner").addClass("hidden");
$("#operations-log-container").empty();
return json.data;
}
},
columnDefs: [
{targets: 0, data: "code" },
{targets: 1, data: "status", render:
function (status) {
var html;
switch (status) {
case "COMPLETED" :
html = "<span><i class='fw fw-ok icon-success'></i> Completed</span>";
break;
case "PENDING" :
html = "<span><i class='fw fw-warning icon-warning'></i> Pending</span>";
break;
case "ERROR" :
html = "<span><i class='fw fw-error icon-danger'></i> Error</span>";
break;
case "IN_PROGRESS" :
html = "<span><i class='fw fw-ok icon-warning'></i> In Progress</span>";
break;
case "REPEATED" :
html = "<span><i class='fw fw-ok icon-warning'></i> Repeated</span>";
break;
}
return html;
}
},
{targets: 2, data: "createdTimeStamp", render:
function (date) {
var value = String(date);
return value.slice(0, 16);
}
}
],
"createdRow": function(row, data) {
$(row).attr("data-type", "selectable");
$(row).attr("data-id", data["id"]);
$.each($("td", row),
function(colIndex) {
switch(colIndex) {
case 1:
$(this).attr("data-grid-label", "Code");
$(this).attr("data-display", data["code"]);
break;
case 2:
$(this).attr("data-grid-label", "Status");
$(this).attr("data-display", data["status"]);
break;
case 3:
$(this).attr("data-grid-label", "Created Timestamp");
$(this).attr("data-display", data["createdTimeStamp"]);
break;
}
}
);
}
});
serverSide: true,
processing: false,
searching: false,
ordering: false,
pageLength : 10,
order: [],
ajax: {
url: "/devicemgt/api/operation/paginate",
data: {deviceId : deviceIdentifier, deviceType: deviceType, owner: deviceOwner},
dataSrc: function (json) {
$("#operations-spinner").addClass("hidden");
$("#operations-log-container").empty();
return json.data;
}
},
columnDefs: [
{targets: 0, data: "code" },
{targets: 1, data: "status", render:
function (status) {
var html;
switch (status) {
case "COMPLETED" :
html = "<span><i class='fw fw-ok icon-success'></i> Completed</span>";
break;
case "PENDING" :
html = "<span><i class='fw fw-warning icon-warning'></i> Pending</span>";
break;
case "ERROR" :
html = "<span><i class='fw fw-error icon-danger'></i> Error</span>";
break;
case "IN_PROGRESS" :
html = "<span><i class='fw fw-ok icon-warning'></i> In Progress</span>";
break;
case "REPEATED" :
html = "<span><i class='fw fw-ok icon-warning'></i> Repeated</span>";
break;
}
return html;
}
},
{targets: 2, data: "createdTimeStamp", render:
function (date) {
var value = String(date);
return value.slice(0, 16);
}
}
],
"createdRow": function(row, data) {
$(row).attr("data-type", "selectable");
$(row).attr("data-id", data["id"]);
$.each($("td", row),
function(colIndex) {
switch(colIndex) {
case 1:
$(this).attr("data-grid-label", "Code");
$(this).attr("data-display", data["code"]);
break;
case 2:
$(this).attr("data-grid-label", "Status");
$(this).attr("data-display", data["status"]);
break;
case 3:
$(this).attr("data-grid-label", "Created Timestamp");
$(this).attr("data-display", data["createdTimeStamp"]);
break;
}
}
);
}
});
}
function loadPolicyCompliance() {
@ -175,7 +178,7 @@
} else {
$("#policy-list-container").
html("<div class='panel-body'><br><p class='fw-warning'> This device " +
"has no policy applied.<p></div>");
"has no policy applied.<p></div>");
}
}
},
@ -183,7 +186,7 @@
function () {
$("#policy-list-container").
html("<div class='panel-body'><br><p class='fw-warning'> Loading policy compliance related data " +
"was not successful. please try refreshing data in a while.<p></div>");
"was not successful. please try refreshing data in a while.<p></div>");
}
);
}
@ -193,7 +196,7 @@
function () {
$("#policy-list-container").
html("<div class='panel-body'><br><p class='fw-warning'> Loading policy compliance related data " +
"was not successful. please try refreshing data in a while.<p></div>");
"was not successful. please try refreshing data in a while.<p></div>");
}
);
}

@ -1,24 +0,0 @@
<table class="table table-striped table-hover table-bordered display data-table" id="operations-log-table">
<thead>
<tr class="sort-row">
<th>Operation Code</th>
<th>Status</th>
<th>Request created at</th>
</tr>
</thead>
<tbody>
{{#each operations}}
<tr data-type="selectable" data-id="{{id}}">
<td data-display="{{code}}" data-grid-label="Code">{{code}}</td>
<td data-display="{{status}}" data-grid-label="Status">
{{#equal status "COMPLETED"}}<span><i class="fw fw-ok icon-success"></i> Completed</span>{{/equal}}
{{#equal status "PENDING"}}<span><i class="fw fw-warning icon-warning"></i> Pending</span>{{/equal}}
{{#equal status "ERROR"}}<span><i class="fw fw-error icon-danger"></i> Error</span>{{/equal}}
{{#equal status "IN_PROGRESS"}}<span><i class="fw fw-ok icon-warning"></i> In Progress</span>{{/equal}}
</td>
<td data-display="{{createdTimeStamp}}" data-grid-label="Created Timestamp">{{createdTimeStamp}}</td>
</tr>
{{/each}}
<br class="c-both" />
</tbody>
</table>

@ -59,141 +59,108 @@
</div>
</div>
{{#defineZone "device-detail-properties"}}
<div class="media">
<div class="media-left col-xs-12 col-sm-2 col-md-2 col-lg-2">
<ul class="list-group" role="tablist">
<li class="active"><a class="list-group-item"
href="#device_details"
role="tab" data-toggle="tab"
aria-controls="device_details">Device
Details</a>
</li>
<li><a class="list-group-item" href="#policies"
role="tab"
data-toggle="tab" aria-controls="policies">Policies</a>
</li>
<li><a class="list-group-item" href="#policy_compliance"
role="tab"
data-toggle="tab" aria-controls="policy_compliance">Policy
Compliance</a>
</li>
<li><a class="list-group-item" href="#device_location"
role="tab"
data-toggle="tab" aria-controls="device_location">Device
Location</a>
</li>
<li><a class="list-group-item" href="#event_log" role="tab"
data-toggle="tab" aria-controls="event_log">Operations
Log</a></li>
</ul>
</div>
<div class="media-body add-padding-left-5x remove-padding-xs tab-content">
<div class="panel-group tab-content">
<div class="panel panel-default tab-pane active"
id="device_details" role="tabpanel"
aria-labelledby="device_details">
{{unit "cdmf.unit.device.details" device=device}}
</div>
<div class="panel panel-default tab-pane" id="policies" role="tabpanel"
aria-labelledby="policies">
<div class="panel-heading">Policies</div>
<div class="panel-body">
<div id="policy-spinner" class="wr-advance-operations-init hidden">
<br>
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading Policies . . .
<br>
<br>
</div>
<div id="policy-list-container">
<div class="panel-body">
No policies found
</div>
<br class="c-both" />
</div>
<div class="media tab-responsive">
<div class="media-left col-xs-1 col-sm-1 col-md-2 col-lg-2 hidden-xs">
<ul class="list-group nav nav-pills nav-stacked" role="tablist">
{{#defineZone "device-view-tabs"}}
{{#defineZone "device-details-tab"}}
<li role="presentation" class="list-group-item active">
<a href="#device_details_tab" role="tab" data-toggle="tab"
aria-controls="device_details_tab">
<i class="icon fw fw-mobile"></i><span class="hidden-sm">Device Details</span>
</a>
</li>
{{/defineZone}}
{{#defineZone "device-details-tab-injected"}}
{{/defineZone}}
{{#defineZone "device-details-tab-operations"}}
<li role="presentation" class="list-group-item">
<a href="#event_log_tab" role="tab" data-toggle="tab" aria-controls="event_log_tab">
<i class="icon fw fw-text"></i><span class="hidden-sm">Operations Log</span>
</a>
</li>
{{/defineZone}}
{{/defineZone}}
</ul>
</div>
<div class="media-body add-padding-left-5x remove-padding-xs">
<div class="panel-group tab-content remove-padding" id="tabs" role="tablist"
data-status="{{device.isNotRemoved}}" aria-multiselectable="true">
<div class="arrow-left hidden-xs"></div>
{{#defineZone "device-view-tab-contents"}}
{{#defineZone "device-details-tab-contents"}}
<div class="message message-info">
<h4 class="remove-margin">
<i class="icon fw fw-info"></i>
No Device details avaialbe yet.
</h4>
</div>
<a class="padding-left"
href="{{@app.context}}/policy/add/{{device.type}}?deviceId={{device.deviceIdentifier}}">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-policy fw-stack-1x"></i>
</span> Add device specific policy</a>
</div>
<div class="panel panel-default tab-pane" id="policy_compliance"
role="tabpanel" aria-labelledby="policy_compliance">
<div class="panel-heading">Policy Compliance <span><a
href="#" id="refresh-policy"><i
class="fw fw-refresh"></i></a></span></div>
<div class="panel-body">
<div id="policy-spinner"
class="wr-advance-operations-init hidden">
<br>
{{/defineZone}}
<i class="fw fw-settings fw-spin fw-2x"></i>
{{#defineZone "device-view-tab-injected-conents"}}
{{/defineZone}}
Loading Policy Compliance . . .
<br>
<br>
{{#defineZone "device-view-tab-operations-log-conents"}}
<div class="panel panel-default visible-xs-block" role="tabpanel" id="event_log_tab">
<div class="panel-heading visible-xs collapsed" id="event_log">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#tabs"
href="#collapseFive" aria-expanded="true" aria-controls="collapseFive">
<i class="fw fw-text fw-2x"></i>
Operations Log
<i class="caret-updown fw fw-down"></i>
</a>
</h4>
</div>
<div id="policy-list-container">
<div class="panel-body">
Not available yet
</div>
<br class="c-both" />
</div>
</div>
</div>
<div class="panel panel-default tab-pane" id="device_location"
role="tabpanel" aria-labelledby="device_location">
<div class="panel-heading">Device Location</div>
<div class="panel-body">
<div id="device-location"
data-lat="{{device.viewModel.location.latitude}}"
data-long="{{device.viewModel.location.longitude}}"
style="height:450px" class="panel-body">
</div>
<div id="map-error" class="panel-body">
Not available yet
</div>
<br class="c-both" />
</div>
</div>
<div class="panel panel-default tab-pane" id="event_log"
role="tabpanel" aria-labelledby="event_log">
<div class="panel-heading">Operations Log <span><a href="#"
id="refresh-operations"><i
class="fw fw-refresh"></i></a></span></div>
<div class="panel-body">
<div id="operations-spinner"
class="wr-advance-operations-init hidden">
<br>
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading Operations Log . . .
<br>
<br>
<div class="panel-heading display-none-xs">
Operations Log
<span>
<a href="javascript:void(0);" id="refresh-operations">
<i class="fw fw-refresh"></i>
</a>
</span>
</div>
<div id="operations-log-container">
<div id="collapseFive" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="event_log">
<div class="panel-body">
Not available yet
<span class="visible-xs add-padding-2x text-right">
<a href="javascript:void(0);" id="refresh-operations">
<i class="fw fw-refresh"></i>
</a>
</span>
<div id="operations-spinner" class="wr-advance-operations-init hidden">
<i class="fw fw-settings fw-spin fw-2x"></i> Loading Operations Log...
</div>
<div id="operations-log-container">
<div class="message message-info">
<h4 class="remove-margin">
<i class="icon fw fw-info"></i>
There are no operations, performed yet on this device.
</h4>
</div>
</div>
<table class="table table-striped table-hover table-bordered display data-table"
id="operations-log-table">
<thead>
<tr class="sort-row">
<th>Operation Code</th>
<th>Status</th>
<th>Request created at</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<br class="c-both" />
</div>
</div>
</div>
</div>
{{/defineZone}}
{{/defineZone}}
</div>
</div>
{{/defineZone}}
</div>
</div>
{{else}}
<h1 class="page-sub-title">
@ -206,6 +173,7 @@
<h1 class="page-sub-title">
Device not found
</h1>
</h1>
<br>
You have tried to access either a removed or non-existing device.
{{/if}}
@ -221,7 +189,4 @@
<script id="applications-list" src="{{@unit.publicUri}}/templates/applications-list.hbs"
data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
type="text/x-handlebars-template"></script>
<script id="operations-log" src="{{@unit.publicUri}}/templates/operations-log.hbs"
data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
type="text/x-handlebars-template"></script>
{{/zone}}

@ -95,8 +95,8 @@ function onRequest(context) {
if (filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_TOTAL_MEMORY"] != 0) {
viewModel["internalMemory"]["usage"] = Math.
round((filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_TOTAL_MEMORY"] -
filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_AVAILABLE_MEMORY"])
/ filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_TOTAL_MEMORY"] * 10000) / 100;
filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_AVAILABLE_MEMORY"])
/ filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_TOTAL_MEMORY"] * 10000) / 100;
} else {
viewModel["internalMemory"]["usage"] = 0;
}
@ -107,8 +107,8 @@ function onRequest(context) {
if (filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_TOTAL_MEMORY"] != 0) {
viewModel["externalMemory"]["usage"] = Math.
round((filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_TOTAL_MEMORY"] -
filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_AVAILABLE_MEMORY"])
/ filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_TOTAL_MEMORY"] * 10000) / 100;
filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_AVAILABLE_MEMORY"])
/ filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_TOTAL_MEMORY"] * 10000) / 100;
} else {
viewModel["externalMemory"]["usage"] = 0;
}
@ -122,8 +122,8 @@ function onRequest(context) {
if (filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["DeviceCapacity"] != 0) {
viewModel["internalMemory"]["usage"] = Math.
round((filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["DeviceCapacity"] -
filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["AvailableDeviceCapacity"])
/ filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["DeviceCapacity"] * 10000) / 100;
filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["AvailableDeviceCapacity"])
/ filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["DeviceCapacity"] * 10000) / 100;
} else {
viewModel["internalMemory"]["usage"] = 0;
}
@ -162,8 +162,8 @@ function onRequest(context) {
if (filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] != 0) {
viewModel["ramUsage"]["value"] = Math.
round((filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] -
filteredDeviceData["latestDeviceInfo"]["availableRAMMemory"])
/ filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] * 10000) / 100;
filteredDeviceData["latestDeviceInfo"]["availableRAMMemory"])
/ filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] * 10000) / 100;
} else {
viewModel["ramUsage"]["value"] = 0;
}
@ -174,8 +174,8 @@ function onRequest(context) {
if (filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] != 0) {
viewModel["internalMemory"]["usage"] = Math.
round((filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] -
filteredDeviceData["latestDeviceInfo"]["internalAvailableMemory"])
/ filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] * 10000) / 100;
filteredDeviceData["latestDeviceInfo"]["internalAvailableMemory"])
/ filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] * 10000) / 100;
} else {
viewModel["internalMemory"]["usage"] = 0;
}
@ -186,8 +186,8 @@ function onRequest(context) {
if (filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] != 0) {
viewModel["externalMemory"]["usage"] = Math.
round((filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] -
filteredDeviceData["latestDeviceInfo"]["externalAvailableMemory"])
/ filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] * 10000) / 100;
filteredDeviceData["latestDeviceInfo"]["externalAvailableMemory"])
/ filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] * 10000) / 100;
} else {
viewModel["externalMemory"]["usage"] = 0;
}
@ -196,7 +196,7 @@ function onRequest(context) {
viewModel["deviceInfoAvailable"] = false;
}
deviceViewData["deviceView"] = viewModel;
deviceViewData["device"] = viewModel;
} else if (response["status"] == "unauthorized") {
deviceViewData["deviceFound"] = true;
deviceViewData["isAuthorized"] = false;

@ -33,12 +33,26 @@
callback(template);
}
};
$.isResourceExists = function (location, callback) {
$.ajax({
url: location,
type: 'HEAD',
success: function () {
callback(true);
},
error: function () {
callback(false);
}
});
};
$.registerPartial = function (name, location, callback) {
$.get(location, function (data) {
Handlebars.registerPartial( name, data);
console.log("Partial " + name + " has been registered");
callback();
});
$.get(location, function (data) {
Handlebars.registerPartial(name, data);
console.log("Partial " + name + " has been registered");
callback();
});
};
})();

@ -36,7 +36,7 @@
{{#zone "topJs"}}
<script type="text/javascript">
var context = "{{@app.context}}"
var context = "{{@app.context}}";
</script>
{{/zone}}

@ -1,78 +1,311 @@
{{!
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"}}
{{#if isAuthorized}}
<span id="logged-in-user" class="hidden" data-username="{{user.username}}" data-domain="{{user.domain}}"
data-tenant-id="{{user.tenantId}}"></span>
<div class="row">
<div class="col-md-12">
<div class="container col-centered wr-content policy-platform">
<div class="wr-steps hidden">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-platform">
<div class="wiz-no">1</div>
<div class="wiz-lbl hidden-xs"><span>Select a platform</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-profile">
<div class="wiz-no">2</div>
<div class="wiz-lbl hidden-xs"><span>Configure profile</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria">
<div class="wiz-no">3</div>
<div class="wiz-lbl hidden-xs"><span>Assign to groups</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming">
<div class="wiz-no">4</div>
<div class="wiz-lbl hidden-xs"><span>Publish to devices</span></div>
</div>
<br class="c-both"/>
</div>
</div>
<div class="col-centered policy-message hidden">
<div class="wr-form">
<h1 id="policy-platform-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is
successful.</h1>
<br>Please click <b>"Add Another Policy"</b>, if you wish to add another policy or click
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message"
data-direct="{{@app.context}}/policies/">
View policy list
</button>
<!--suppress HtmlUnknownTarget -->
<a href="{{@app.context}}/policy/add" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add another policy
</a>
</div>
</div>
<div class="col-centered wr-content policy-naming hidden">
<div class="wr-form">
<h1 id="policy-naming-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-platform-wizard-steps" class="row wr-wizard">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-platform">
<div class="wiz-no">1</div>
<div class="wiz-lbl hidden-xs"><span>Select a platform</span></div>
<div id="policy-naming-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="hidden-xs">Step 4: Publish to devices</h4>
<br>
<div id="policy-naming-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-profile">
<div class="wiz-no">2</div>
<div class="wiz-lbl hidden-xs"><span>Configure profile</span></div>
<div class="clearfix">
<label class="wr-input-label">Set a Name for your Policy *</label>
<br/>
<label class="wr-input-label">
(Policy name should be 1-to-30 characters long)
</label>
<div id="policyNameField" class="wr-input-control">
<div class="cus-col-50 form-group wr-input-control">
<!--suppress HtmlFormInputWithoutLabel -->
<input id="policy-name-input" class="form-control" type="text" value=""/>
<label class="error nameEmpty hidden" for="summary">Policy name is required
&
Should be be 1-to-30
characters long.</label>
</div>
<br class="c-both"/>
</div>
<br class="c-both"/>
<label class="wr-input-label">
Add a description
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<textarea id="policy-description-input" class="form-control" rows="10"
placeholder="[ Summary about the policy ]"></textarea>
</div>
<br class="c-both"/>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-naming" data-next="policy-criteria">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-naming-publish" data-next="policy-message"
data-validate="true">Publish</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-naming"
data-next="policy-message" data-validate="true">Save</a>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria">
<div class="wiz-no">3</div>
<div class="wiz-lbl hidden-xs"><span>Assign</span></div>
</div>
</div>
</div>
<div class="col-centered wr-content policy-criteria hidden">
<div class="wr-form">
<h1 id="policy-criteria-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-criteria-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="hidden-xs">Step 3: Assign to groups</h4>
<br>
<div id="policy-criteria-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<div class="wr-input-control">
{{#if isAuthorizedViewRoles}}
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio"
name="select-users-radio-btn"
class="select-users-radio" checked/>
<span class="helper">Set user role(s)</span>
</label>
{{/if}}
{{#if isAuthorizedViewUsers}}
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio"/>
<span class="helper">Set user(s)</span>
</label>
{{/if}}
</div>
{{#if isAuthorizedViewRoles}}
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="user-roles-input" class="form-control select2"
multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
{{#if isAuthorizedViewUsers}}
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="users-input" class="form-control select2"
multiple="multiple">
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
{{#if isAuthorizedViewGroups}}
<label class="wr-input-label">
Select Groups
</label>
<div id="groups-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="groups-input" class="form-control select2"
multiple="multiple">
<option value="NONE" selected>NONE</option>
{{#each groups}}
<option>{{this.name}}</option>
{{/each}}
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
<br>
<label class="wr-input-label" title="">
Set an action upon non-compliance
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="action-input" class="form-control">
<option data-action="enforce" selected>Enforce</option>
<option data-action="warn">Warn</option>
<option data-action="monitor">Monitor</option>
</select>
</div>
<br class="c-both"/>
</div>
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-criteria" data-next="policy-profile">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-criteria" data-next="policy-naming" data-validate="true">Continue</a>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming">
<div class="wiz-no">4</div>
<div class="wiz-lbl hidden-xs"><span>Publish to devices</span></div>
</div>
</div>
</div>
<div class="col-centered wr-content policy-profile hidden">
<div class="wr-form">
<h1 id="policy-profile-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-profile-wizard-steps" class="row wr-wizard"></div>
<hr>
<div class="row">
<div class="col-lg-12">
<h4 class="hidden-xs">Step 2: Configure profile</h4>
<br>
<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 class="wr-input-control wr-btn-grp">
<a href="javascript:void(0)" class="wr-btn wizard-stepper" data-is-back-btn="true"
data-current="policy-profile" data-next="policy-platform">Back</a>
<a href="javascript:void(0)" class="wr-btn wizard-stepper"
data-current="policy-profile"
data-next="policy-criteria" data-validate="true">Continue</a>
</div>
<br class="c-both"/>
</div>
</div>
</div>
</div>
<div id="loading-content" class="col-centered">
<br><br>
<i class="fw fw-settings fw-spin fw-2x"></i>
Loading policy creation wizard . . .
<br><br>
</div>
<div class=" col-centered wr-content policy-platform hidden">
<div class="wr-form">
<h1 id="policy-platform-page-wizard-title" class="page-sub-title">ADD POLICY</h1>
<hr>
<div id="policy-platform-wizard-steps" class="row wr-wizard"></div>
<hr>
<!--<div id="policy-platform-main-error-msg" class="alert alert-danger hidden" role="alert">-->
<!--<i class="icon fw fw-error"></i><span></span>-->
<!--</div>-->
<div class="row">
<div class="col-lg-12">
<h4>Step 1: Select a platform</h4>
<h4 class="hidden-xs"> Step 1: Select a platform</h4>
<br>
<div id="policy-platform-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
{{#unless types}}
<h3><i class="icon fw fw-warning"></i> No compatible device types have been installed.
Install device types to add policies.</h3>
{{/unless}}
<div class="row wr-tile-buttons-list">
<div class="wr-input-control">
<ul class="tile-buttons row">
{{#each types}}
<li class="col-lg-4"
style="margin-top: 5px;margin-bottom: 5px;">
<a href="{{@app.context}}/policy/add/{{name}}"
class="wizard-stepper">
<img src="{{icon}}" width="50px"
height="50px"><br><br>
<b>{{label}}</b>
</a>
</li>
{{/each}}
{{#if types}}
{{#each types}}
<li class="col-xs-12 col-sm-12 col-md-4 col-lg-4"
style="margin-top: 5px; margin-bottom: 5px;">
<a href="javascript:void(0)"
class="{{name}}-platform wizard-stepper"
data-current="policy-platform"
data-next="policy-profile"
data-platform="{{name}}"
data-validate="false">
<img src="{{icon}}" width="50px" height="50px"><br><br>
<b>{{label}}</b>
</a>
</li>
{{/each}}
{{/if}}
</ul>
</div>
</div>
@ -83,12 +316,8 @@
<!-- content -->
</div>
</div>
{{else}}
<h1 class="page-sub-title">
Permission Denied
</h1>
<br>
You not authorized to enter Policy Management Section.
<br>
{{/if}}
{{/zone}}
{{#zone "bottomJs"}}
{{js "/js/policy-create.js"}}
{{/zone}}

@ -23,12 +23,15 @@ function onRequest(context) {
var utility = require("/app/modules/utility.js").utility;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var groupModule = require("/app/modules/business-controllers/group.js")["groupModule"];
var types = {};
types.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
types.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
types.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
types.isAuthorizedViewGroups = userModule.isAuthorized("/permission/admin/device-mgt/groups/view");
types["types"] = [];
var typesListResponse = deviceModule.getDeviceTypes();
if (typesListResponse["status"] == "success") {
for (var type in typesListResponse["content"]["deviceTypes"]) {
@ -48,5 +51,14 @@ function onRequest(context) {
}
}
}
var user = userModule.getCarbonUser();
types["user"] = {username: user.username, domain: user.domain, tenantId: user.tenantId};
var roles = userModule.getRoles();
if (roles["status"] == "success") {
types["roles"] = roles["content"];
}
types["groups"] = groupModule.getGroups();
return types;
}

@ -0,0 +1,613 @@
/*
*
* 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 stepForwardFrom = {};
var stepBackFrom = {};
var policy = {};
var configuredOperations = [];
var validateInline = {};
var clearInline = {};
var validateStep = {};
var enableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
if (inputField) {
$(fieldIdentifier).addClass(" has-error has-feedback");
}
if (errorMsg) {
$(errorMsgIdentifier).removeClass(" hidden");
}
if (errorSign) {
$(errorSignIdentifier).removeClass(" hidden");
}
};
var disableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
if (inputField) {
$(fieldIdentifier).removeClass(" has-error has-feedback");
}
if (errorMsg) {
$(errorMsgIdentifier).addClass(" hidden");
}
if (errorSign) {
$(errorSignIdentifier).addClass(" hidden");
}
};
/**
* Load all device groups.
*
* @param callback function to call on loading completion.
*/
function loadGroups(callback) {
invokerUtil.get(
"/api/device-mgt/v1.0/groups",
function (data) {
data = JSON.parse(data);
callback(data.deviceGroups);
});
}
/**
* Creates DeviceGroupWrapper object from selected groups.
*
* @param selectedGroups
* @returns {Array} DeviceGroupWrapper list.
*/
var createDeviceGroupWrapper = function (selectedGroups) {
var groupObjects = [];
loadGroups(function (deviceGroups) {
var tenantId = $("#logged-in-user").data("tenant-id");
for (var index in deviceGroups) {
if(deviceGroups.hasOwnProperty(index)) {
var deviceGroupWrapper = {};
if (selectedGroups.indexOf(deviceGroups[index].name) > -1) {
deviceGroupWrapper.id = deviceGroups[index].id;
deviceGroupWrapper.name = deviceGroups[index].name;
deviceGroupWrapper.owner = deviceGroups[index].owner;
deviceGroupWrapper.tenantId = tenantId;
groupObjects.push(deviceGroupWrapper);
}
}
}
});
return groupObjects;
};
/**
*clear inline validation messages.
*/
clearInline["policy-name"] = function () {
disableInlineError("policyNameField", "nameEmpty", "nameError");
};
/**
* Validate if provided policy name is valid against RegEx configures.
*/
validateInline["policy-name"] = function () {
var policyName = $("input#policy-name-input").val();
if (policyName && inputIsValidAgainstLength(policyName, 1, 30)) {
disableInlineError("policyNameField", "nameEmpty", "nameError");
} else {
enableInlineError("policyNameField", "nameEmpty", "nameError");
}
};
$("#policy-name-input").focus(function(){
clearInline["policy-name"]();
}).blur(function(){
validateInline["policy-name"]();
});
/**
* Forward action of device type selection step. Loads relevant policy profile configurations.
*
* @param actionButton
*/
stepForwardFrom["policy-platform"] = function (actionButton) {
$("#device-type-policy-operations").html("").addClass("hidden");
$("#generic-policy-operations").addClass("hidden");
policy["platform"] = $(actionButton).data("platform");
policy["platformId"] = $(actionButton).data("platform-type");
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/templates/' + deviceType + '-policy-operations.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/js/' + deviceType + '-policy-operations.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/css/' + deviceType + '-policy-operations.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);
}
});
$.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");
});
};
/**
* Forward action of policy profile page. Generates policy profile payload.
*/
stepForwardFrom["policy-profile"] = function () {
policy["profile"] = operationModule.generateProfile(policy["platform"], configuredOperations);
// updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
};
/**
* Backward action of policy profile page. Moves back to platform selection step.
*/
stepBackFrom["policy-profile"] = function () {
// reinitialize configuredOperations
configuredOperations = [];
};
/**
* Forward action of policy criteria page.
*/
stepForwardFrom["policy-criteria"] = function () {
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(':radio')) {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
policy["selectedUsers"] = $("#users-input").val();
policy["selectedUserRoles"] = null;
} else if ($(this).attr("id") == "user-roles-radio-btn") {
policy["selectedUsers"] = null;
policy["selectedUserRoles"] = $("#user-roles-input").val();
}
}
}
});
policy["selectedGroups"] = $("#groups-input").val();
if (policy["selectedGroups"] && (policy["selectedGroups"].length > 1 || policy["selectedGroups"][0] !== "NONE")) {
policy["selectedGroups"] = createDeviceGroupWrapper(policy["selectedGroups"]);
}
policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action");
//updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
};
/**
* Checks if provided input is valid against provided length range.
*
* @param input Alphanumeric or non-alphanumeric input
* @param minLength Minimum Required Length
* @param maxLength Maximum Required Length
* @returns {boolean} Returns true if input matches the provided minimum length and maximum length
*/
var inputIsValidAgainstLength = function (input, minLength, maxLength) {
var length = input.length;
return (length == minLength || (length > minLength && length < maxLength) || length == maxLength);
};
/**
* Validates policy criteria inputs.
*
* @returns {boolean} whether the validation is successful.
*/
validateStep["policy-criteria"] = function () {
var validationStatus = {};
var selectedAssignees;
var selectedField = "Role(s)";
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
selectedAssignees = $("#users-input").val();
selectedField = "User(s)";
} else if ($(this).attr("id") == "user-roles-radio-btn") {
selectedAssignees = $("#user-roles-input").val();
}
return false;
}
});
if (selectedAssignees) {
validationStatus["error"] = false;
} else {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = selectedField + " is a required field. It cannot be empty";
}
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-criteria-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
/**
* Validating policy naming.
*
* @returns {boolean} whether the validation is successful.
*/
validateStep["policy-naming"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-platform"] = function () {
return false;
};
validateStep["policy-naming-publish"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
stepForwardFrom["policy-naming-publish"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
savePolicy(policy, true, "/api/device-mgt/v1.0/policies/");
};
stepForwardFrom["policy-naming"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
savePolicy(policy, false, "/api/device-mgt/v1.0/policies/");
};
var savePolicy = function (policy, isActive, serviceURL) {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
$.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;
}
});
});
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": null,
"active": isActive,
"profile": {
"profileName": policy["policyName"],
"deviceType": policy["platform"],
"profileFeaturesList": profilePayloads
}
};
if (policy["selectedUsers"]) {
payload["users"] = policy["selectedUsers"];
} else if (policy["selectedUserRoles"]) {
payload["roles"] = policy["selectedUserRoles"];
} else {
payload["users"] = [];
payload["roles"] = [];
}
if(policy["selectedGroups"] && policy["selectedGroups"][0] !== "NONE") {
payload["deviceGroups"] = policy["selectedGroups"];
}
invokerUtil.post(
serviceURL,
payload,
function () {
$(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden");
},
function (data) {
}
);
};
function formatRepo(user) {
if (user.loading) {
return user.text;
}
if (!user.username) {
return;
}
var markup = '<div class="clearfix">' +
'<div clas="col-sm-8">' +
'<div class="clearfix">' +
'<div class="col-sm-3">' + user.username + '</div>';
if (user.firstname) {
markup += '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + user.firstname + '</div>';
}
if (user.emailAddress) {
markup += '<div class="col-sm-2"><i class="fa fa-star"></i> ' + user.emailAddress + '</div></div>';
}
markup += '</div></div>';
return markup;
}
function formatRepoSelection(user) {
return user.username || user.text;
}
// End of functions related to grid-input-view
$(document).ready(function () {
$("#users-input").select2({
multiple: true,
tags: false,
ajax: {
url: context + "/api/invoker/execute/",
method: "POST",
dataType: 'json',
delay: 250,
id: function (user) {
return user.username;
},
data: function (params) {
var postData = {};
postData.requestMethod = "GET";
postData.requestURL = "/api/device-mgt/v1.0/users/search/usernames?filter=" + params.term;
postData.requestPayload = null;
return JSON.stringify(postData);
},
processResults: function (data) {
var newData = [];
$.each(data, function (index, value) {
value.id = value.username;
newData.push(value);
});
return {
results: newData
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
}, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
$("#loading-content").remove();
$(".policy-platform").removeClass("hidden");
// Adding initial state of wizard-steps.
$("#policy-platform-wizard-steps").html($(".wr-steps").html());
$("select.select2[multiple=multiple]").select2({
"tags": false
});
$("#users-select-field").hide();
$("#user-roles-select-field").show();
$("input[type='radio'].select-users-radio").change(function () {
if ($("#users-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
$("#users-select-field").show();
}
if ($("#user-roles-radio-btn").is(":checked")) {
$("#users-select-field").hide();
$("#user-roles-select-field").show();
}
});
// Support for special input type "ANY" on user(s) & user-role(s) selection
$("#user-roles-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
} else {
$("option[value=ANY]", this).prop("selected", false).parent().trigger("change");
}
});
$("#groups-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "NONE") {
$(this).val("NONE").trigger("change");
} else {
$("option[value=NONE]", this).prop("selected", false).parent().trigger("change");
}
});
//Policy wizard stepper
$(".wizard-stepper").click(function () {
// button clicked here can be either a continue button or a back button.
var currentStep = $(this).data("current");
var validationIsRequired = $(this).data("validate");
var wizardIsToBeContinued;
if (validationIsRequired) {
if (currentStep == "policy-profile") {
wizardIsToBeContinued = validatePolicyProfile();
} else {
wizardIsToBeContinued = validateStep[currentStep]();
}
} else {
wizardIsToBeContinued = true;
}
if (wizardIsToBeContinued) {
// When moving back and forth, following code segment will
// remove if there are any visible error-messages.
var errorMsgWrappers = ".alert.alert-danger";
$(errorMsgWrappers).each(
function () {
if (!$(this).hasClass("hidden")) {
$(this).addClass("hidden");
}
}
);
var nextStep = $(this).data("next");
var isBackBtn = $(this).data("is-back-btn");
// if current button is a continuation...
if (!isBackBtn) {
// initiate stepForwardFrom[*] functions to gather form data.
if (stepForwardFrom[currentStep]) {
stepForwardFrom[currentStep](this);
}
} else {
// initiate stepBackFrom[*] functions to rollback.
if (stepBackFrom[currentStep]) {
stepBackFrom[currentStep]();
}
}
// following step occurs only at the last stage of the wizard.
if (!nextStep) {
window.location.href = $(this).data("direct");
}
// updating next wizard step as current.
$(".itm-wiz").each(function () {
var step = $(this).data("step");
if (step == nextStep) {
$(this).addClass("itm-wiz-current");
} else {
$(this).removeClass("itm-wiz-current");
}
});
// adding next update of wizard-steps.
$("#" + nextStep + "-wizard-steps").html($(".wr-steps").html());
// hiding current section of the wizard and showing next section.
$("." + currentStep).addClass("hidden");
$("." + nextStep).removeClass("hidden");
}
});
});

@ -1,5 +1,7 @@
{{#zone "content"}}
{{#if isAuthorized }}
<span id="logged-in-user" class="hidden" data-username="{{user.username}}" data-domain="{{user.domain}}"
data-tenant-id="{{user.tenantId}}"></span>
<div class="row">
<div class="col-md-12">
@ -35,10 +37,10 @@
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message"
data-direct="/emm/policies/">
data-direct="{{@app.context}}/policies/">
View policy list
</button>
<a href="/emm/policies/add-policy" class="cu-btn-inner">
<a href="{{@app.context}}/policies/add" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
@ -61,7 +63,7 @@
<div id="policy-naming-main-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<div class="clearfix">
<label class="wr-input-label">
Set a name * to your policy<br>
( should be 1-to-30 characters long )
@ -121,60 +123,73 @@
<i class="icon fw fw-error"></i><span></span>
</div>
<div>
<label class="wr-input-label">
Set device ownership type
</label>
<div class="wr-input-control">
<div class="cus-col-50">
<select id="ownership-input" class="form-control">
<option value="ANY" selected>ANY</option>
<option value="BYOD">BYOD (Bring Your Own Device)</option>
<option value="COPE">COPE (Corporate-Owned, Personally Enabled)</option>
</select>
</div>
<br class="c-both"/>
</div>
<div class="wr-input-control">
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio" checked/>
<span class="helper">Set user role(s)</span>
</label>
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio"/>
<span class="helper">Set user(s)</span>
</label>
{{#if isAuthorizedViewRoles}}
<label class="wr-input-control radio light">
<input id="user-roles-radio-btn" type="radio"
name="select-users-radio-btn"
class="select-users-radio" checked/>
<span class="helper">Set user role(s)</span>
</label>
{{/if}}
{{#if isAuthorizedViewUsers}}
<label class="wr-input-control radio light" rel="assetfilter">
<input id="users-radio-btn" type="radio" name="select-users-radio-btn"
class="select-users-radio"/>
<span class="helper">Set user(s)</span>
</label>
{{/if}}
</div>
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="user-roles-input" class="form-control select2"
multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
{{#if isAuthorizedViewRoles}}
<div id="user-roles-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="user-roles-input" class="form-control select2"
multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each roles}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
<br class="c-both"/>
</div>
<br class="c-both"/>
</div>
</div>
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<select id="users-input" class="form-control select2"
multiple="multiple">
<option value="ANY" selected>ANY</option>
{{#each users}}
<option>{{username}}</option>
{{/each}}
</select>
{{/if}}
{{#if isAuthorizedViewUsers}}
<div id="users-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="users-input" class="form-control select2"
multiple="multiple">
</select>
</div>
<br class="c-both"/>
</div>
<br class="c-both"/>
</div>
</div>
<br>
{{/if}}
{{#if isAuthorizedViewGroups}}
<label class="wr-input-label">
Select Groups
</label>
<div id="groups-select-field" class="select-users">
<div class="wr-input-control">
<div class="cus-col-50">
<!--suppress HtmlFormInputWithoutLabel -->
<select id="groups-input" class="form-control select2"
multiple="multiple">
<option value="NONE" selected>NONE</option>
{{#each groups}}
<option>{{this.name}}</option>
{{/each}}
</select>
</div>
<br class="c-both"/>
</div>
</div>
{{/if}}
<label class="wr-input-label" title="">
Set an action upon non-compliance
</label>
@ -218,13 +233,17 @@
<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 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 class="wr-input-control wr-btn-grp">
@ -252,15 +271,5 @@
{{/if}}
{{/zone}}
{{#zone "bottomJs"}}
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-ios" src="{{@unit.publicUri}}/templates/hidden-operations-ios.hbs"
type="text/x-handlebars-template"></script>
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-android" src="{{@unit.publicUri}}/templates/hidden-operations-android.hbs"
type="text/x-handlebars-template"></script>
<!--suppress HtmlUnknownTarget -->
<script id="hidden-operations-windows" src="{{@unit.publicUri}}/templates/hidden-operations-windows.hbs"
type="text/x-handlebars-template"></script>
{{js "js/edit.js"}}
{{js "js/policy-edit.js"}}
{{/zone}}

@ -18,19 +18,29 @@
function onRequest(context) {
var log = new Log("policy-view-edit-unit backend js");
log.debug("calling policy-view-edit-unit");
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var groupModule = require("/app/modules/business-controllers/group.js")["groupModule"];
var rolesResult = userModule.getRoles();
if (rolesResult.status == "success") {
viewModel.roles = rolesResult.content;
context.roles = rolesResult.content;
}
var usersResult = userModule.getUsers();
if (usersResult.status == "success") {
viewModel.users = usersResult.content;
context.users = usersResult.content;
}
viewModel.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
return viewModel;
context["groups"] = groupModule.getGroups();
var user = userModule.getCarbonUser();
context["user"] = {username: user.username, domain: user.domain, tenantId: user.tenantId};
context.isAuthorized = userModule.isAuthorized("/permission/admin/device-mgt/policies/manage");
context.isAuthorizedViewUsers = userModule.isAuthorized("/permission/admin/device-mgt/roles/view");
context.isAuthorizedViewRoles = userModule.isAuthorized("/permission/admin/device-mgt/users/view");
context.isAuthorizedViewGroups = userModule.isAuthorized("/permission/admin/device-mgt/groups/view");
return context;
}

@ -0,0 +1,651 @@
/*
* 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 validateStep = {};
var skipStep = {};
var stepForwardFrom = {};
var stepBackFrom = {};
var configuredOperations = [];
var policy = {};
var currentlyEffected = {};
var validateInline = {};
var clearInline = {};
var enableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
if (inputField) {
$(fieldIdentifier).addClass(" has-error has-feedback");
}
if (errorMsg) {
$(errorMsgIdentifier).removeClass(" hidden");
}
if (errorSign) {
$(errorSignIdentifier).removeClass(" hidden");
}
};
var disableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
if (inputField) {
$(fieldIdentifier).removeClass(" has-error has-feedback");
}
if (errorMsg) {
$(errorMsgIdentifier).addClass(" hidden");
}
if (errorSign) {
$(errorSignIdentifier).addClass(" hidden");
}
};
/**
* Load all device groups.
*
* @param callback function to call on loading completion.
*/
function loadGroups(callback) {
invokerUtil.get(
"/api/device-mgt/v1.0/groups",
function (data) {
data = JSON.parse(data);
callback(data.deviceGroups);
});
}
/**
* Creates DeviceGroupWrapper object from selected groups.
*
* @param selectedGroups
* @returns {Array} DeviceGroupWrapper list.
*/
var createDeviceGroupWrapper = function (selectedGroups) {
var groupObjects = [];
loadGroups(function (deviceGroups) {
var tenantId = $("#logged-in-user").data("tenant-id");
for (var index in deviceGroups) {
if (deviceGroups.hasOwnProperty(index)) {
var deviceGroupWrapper = {};
if (selectedGroups.indexOf(deviceGroups[index].name) > -1) {
deviceGroupWrapper.id = deviceGroups[index].id;
deviceGroupWrapper.name = deviceGroups[index].name;
deviceGroupWrapper.owner = deviceGroups[index].owner;
deviceGroupWrapper.tenantId = tenantId;
groupObjects.push(deviceGroupWrapper);
}
}
}
});
return groupObjects;
};
/**
*clear inline validation messages.
*/
clearInline["policy-name"] = function () {
disableInlineError("policy-name-field", "nameEmpty", "nameError");
};
/**
* Validate if provided policy name is valid against RegEx configures.
*/
validateInline["policy-name"] = function () {
var policyName = $("input#policy-name-input").val();
if (policyName && inputIsValidAgainstLength(policyName, 1, 30)) {
disableInlineError("policy-name-field", "nameEmpty", "nameError");
} else {
enableInlineError("policy-name-field", "nameEmpty", "nameError");
}
};
$("#policy-name-input").focus(function () {
clearInline["policy-name"]();
}).blur(function () {
validateInline["policy-name"]();
});
skipStep["policy-platform"] = function (policyPayloadObj) {
policy["name"] = policyPayloadObj["policyName"];
policy["platform"] = policyPayloadObj["profile"]["deviceType"];
var userRoleInput = $("#user-roles-input");
var ownershipInput = $("#ownership-input");
var userInput = $("#users-input");
var groupsInput = $("#groups-input");
var actionInput = $("#action-input");
var policyNameInput = $("#policy-name-input");
var policyDescriptionInput = $("#policy-description-input");
currentlyEffected["roles"] = policyPayloadObj.roles;
currentlyEffected["users"] = policyPayloadObj.users;
currentlyEffected["groups"] = [];
if (policyPayloadObj.deviceGroups) {
var deviceGroups = policyPayloadObj.deviceGroups;
for (var index in deviceGroups) {
if (deviceGroups.hasOwnProperty(index)) {
currentlyEffected["groups"].push(deviceGroups[index].name);
}
}
} else {
currentlyEffected["groups"].push("NONE");
}
if (currentlyEffected["roles"].length > 0) {
$("#user-roles-radio-btn").prop("checked", true);
$("#user-roles-select-field").show();
$("#users-select-field").hide();
userRoleInput.val(currentlyEffected["roles"]).trigger("change");
} else if (currentlyEffected["users"].length > 0) {
$("#users-radio-btn").prop("checked", true);
$("#users-select-field").show();
$("#user-roles-select-field").hide();
userInput.val(currentlyEffected["users"]).trigger("change");
}
if (currentlyEffected["groups"].length > 0) {
groupsInput.val(currentlyEffected["groups"]).trigger("change");
}
ownershipInput.val(policyPayloadObj.ownershipType);
actionInput.val(policyPayloadObj.compliance);
policyNameInput.val(policyPayloadObj["policyName"]);
policyDescriptionInput.val(policyPayloadObj["description"]);
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-edit/templates/' + deviceType + '-policy-edit.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-edit/js/' + deviceType + '-policy-edit.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-edit/css/' + deviceType + '-policy-edit.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);
var configuredOperations = operationModule.populateProfile(policy["platform"],
policyPayloadObj["profile"]["profileFeaturesList"]);
polulateProfileOperations(configuredOperations);
}
});
});
$.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");
});
};
/**
* Forward action of policy profile page. Generates policy profile payload.
*/
stepForwardFrom["policy-profile"] = function () {
policy["profile"] = operationModule.generateProfile(policy["platform"], configuredOperations);
// updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
};
/**
* Forward action of policy criteria page.
*/
stepForwardFrom["policy-criteria"] = function () {
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(':radio')) {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
policy["selectedUsers"] = $("#users-input").val();
policy["selectedUserRoles"] = null;
} else if ($(this).attr("id") == "user-roles-radio-btn") {
policy["selectedUsers"] = null;
policy["selectedUserRoles"] = $("#user-roles-input").val();
}
}
}
});
policy["selectedGroups"] = $("#groups-input").val();
if (policy["selectedGroups"] && (policy["selectedGroups"].length > 1 || policy["selectedGroups"][0] !== "NONE")) {
policy["selectedGroups"] = createDeviceGroupWrapper(policy["selectedGroups"]);
}
policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action");
policy["selectedOwnership"] = $("#ownership-input").val();
// updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("EDIT " + policy["platform"] + " POLICY - " + policy["name"]);
};
/**
* Checks if provided input is valid against provided length range.
*
* @param input Alphanumeric or non-alphanumeric input
* @param minLength Minimum Required Length
* @param maxLength Maximum Required Length
* @returns {boolean} Returns true if input matches the provided minimum length and maximum length
*/
var inputIsValidAgainstLength = function (input, minLength, maxLength) {
var length = input.length;
return (length == minLength || (length > minLength && length < maxLength) || length == maxLength);
};
/**
* Validates policy criteria inputs.
*
* @returns {boolean} whether the validation is successful.
*/
validateStep["policy-criteria"] = function () {
var validationStatus = {};
var selectedAssignees;
var selectedField = "Role(s)";
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
selectedAssignees = $("#users-input").val();
selectedField = "User(s)";
} else if ($(this).attr("id") == "user-roles-radio-btn") {
selectedAssignees = $("#user-roles-input").val();
}
return false;
}
});
if (selectedAssignees) {
validationStatus["error"] = false;
} else {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = selectedField + " is a required field. It cannot be empty";
}
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-criteria-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
/**
* Validating policy naming.
*
* @returns {boolean} whether the validation is successful.
*/
validateStep["policy-naming"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-naming-publish"] = function () {
var validationStatus = {};
// taking values of inputs to be validated
var policyName = $("input#policy-name-input").val();
// starting validation process and updating validationStatus
if (!policyName) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = "Policy name is empty. You cannot proceed.";
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
// ending validation process
// start taking specific actions upon validation
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-naming-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
stepForwardFrom["policy-naming-publish"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
updatePolicy(policy, "publish");
};
stepForwardFrom["policy-naming"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
updatePolicy(policy, "save");
};
// End of functions related to grid-input-view
/**
* 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, " "));
};
var updatePolicy = function (policy, state) {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
$.each(profilePayloads, function (i, item) {
$.each(item.content, function (key, value) {
if (value === null || value === undefined || value === "") {
item.content[key] = null;
}
});
});
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": null,
"profile": {
"profileName": policy["policyName"],
"deviceType": policy["platform"],
"profileFeaturesList": profilePayloads
}
};
if (policy["selectedUsers"]) {
payload["users"] = policy["selectedUsers"];
payload["roles"] = [];
} else if (policy["selectedUserRoles"]) {
payload["users"] = [];
payload["roles"] = policy["selectedUserRoles"];
} else {
payload["users"] = [];
payload["roles"] = [];
}
if (policy["selectedGroups"] && policy["selectedGroups"][0] !== "NONE") {
payload["deviceGroups"] = policy["selectedGroups"];
}
var serviceURL = "/api/device-mgt/v1.0/policies/" + getParameterByName("id");
invokerUtil.put(
serviceURL,
payload,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
var policyList = [];
policyList.push(getParameterByName("id"));
if (state == "save") {
serviceURL = "/api/device-mgt/v1.0/policies/deactivate-policy";
invokerUtil.post(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
$(".add-policy").addClass("hidden");
$(".policy-message").removeClass("hidden");
}
},
// on error
function (jqXHR) {
console.log("error in saving policy. Received error code : " + jqXHR.status);
}
);
} else if (state == "publish") {
serviceURL = "/api/device-mgt/v1.0/policies/activate-policy";
invokerUtil.post(
serviceURL,
policyList,
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) {
$(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden");
}
},
// on error
function (jqXHR) {
console.log("error in publishing policy. Received error code : " + jqXHR.status);
}
);
}
}
},
// on error
function (jqXHR) {
console.log("error in updating policy. Received error code : " + jqXHR.status);
}
);
};
$(document).ready(function () {
// Adding initial state of wizard-steps.
invokerUtil.get(
"/api/device-mgt/v1.0/policies/" + getParameterByName("id"),
// on success
function (data, textStatus, jqXHR) {
if (jqXHR.status == 200 && data) {
var policy = JSON.parse(data);
skipStep["policy-platform"](policy);
}
},
// on error
function (jqXHR) {
console.log(jqXHR);
// should be redirected to an error page
}
);
$("input[type='radio'].select-users-radio").change(function () {
if ($("#users-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
$("#users-select-field").show();
}
if ($("#user-roles-radio-btn").is(":checked")) {
$("#users-select-field").hide();
$("#user-roles-select-field").show();
}
});
// Support for special input type "ANY" on user(s) & user-role(s) selection
$("#user-roles-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
} else {
$("option[value=ANY]", this).prop("selected", false).parent().trigger("change");
}
});
$("#groups-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "NONE") {
$(this).val("NONE").trigger("change");
} else {
$("option[value=NONE]", this).prop("selected", false).parent().trigger("change");
}
});
$("#users-input").select2({
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
} else {
$("option[value=ANY]", this).prop("selected", false).parent().trigger("change");
}
});
$("#policy-profile-wizard-steps").html($(".wr-steps").html());
$(".wizard-stepper").click(function () {
// button clicked here can be either a continue button or a back button.
var currentStep = $(this).data("current");
var validationIsRequired = $(this).data("validate");
var wizardIsToBeContinued;
if (validationIsRequired) {
if (currentStep == "policy-profile") {
wizardIsToBeContinued = validatePolicyProfile();
} else {
wizardIsToBeContinued = validateStep[currentStep]();
}
} else {
wizardIsToBeContinued = true;
}
if (wizardIsToBeContinued) {
// When moving back and forth, following code segment will
// remove if there are any visible error-messages.
var errorMsgWrappers = ".alert.alert-danger";
$(errorMsgWrappers).each(
function () {
if (!$(this).hasClass("hidden")) {
$(this).addClass("hidden");
}
}
);
var nextStep = $(this).data("next");
var isBackBtn = $(this).data("is-back-btn");
// if current button is a continuation...
if (!isBackBtn) {
// initiate stepForwardFrom[*] functions to gather form data.
if (stepForwardFrom[currentStep]) {
stepForwardFrom[currentStep](this);
}
} else {
// initiate stepBackFrom[*] functions to rollback.
if (stepBackFrom[currentStep]) {
stepBackFrom[currentStep]();
}
}
// following step occurs only at the last stage of the wizard.
if (!nextStep) {
window.location.href = $(this).data("direct");
}
// updating next wizard step as current.
$(".itm-wiz").each(function () {
var step = $(this).data("step");
if (step == nextStep) {
$(this).addClass("itm-wiz-current");
} else {
$(this).removeClass("itm-wiz-current");
}
});
// adding next update of wizard-steps.
$("#" + nextStep + "-wizard-steps").html($(".wr-steps").html());
// hiding current section of the wizard and showing next section.
$("." + currentStep).addClass("hidden");
$("." + nextStep).removeClass("hidden");
}
});
});

@ -1,17 +1,16 @@
/*
* 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
* 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
* "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.
*/
@ -21,60 +20,120 @@ var stepForwardFrom = {};
var stepBackFrom = {};
var policy = {};
var configuredOperations = [];
var deviceTypeLabel;
var validateInline = {};
var clearInline = {};
/**
* Method to update the visibility of grouped input.
* @param domElement HTML grouped-input element with class name "grouped-input"
*/
var updateGroupedInputVisibility = function (domElement) {
if ($(".parent-input:first", domElement).is(":checked")) {
if ($(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).removeClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', false);
});
} else {
if (!$(".grouped-child-input:first", domElement).hasClass("disabled")) {
$(".grouped-child-input:first", domElement).addClass("disabled");
}
$(".child-input", domElement).each(function () {
$(this).prop('disabled', true);
});
var enableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
if (inputField) {
$(fieldIdentifier).addClass(" has-error has-feedback");
}
if (errorMsg) {
$(errorMsgIdentifier).removeClass(" hidden");
}
if (errorSign) {
$(errorSignIdentifier).removeClass(" hidden");
}
};
var disableInlineError = function (inputField, errorMsg, errorSign) {
var fieldIdentifier = "#" + inputField;
var errorMsgIdentifier = "#" + inputField + " ." + errorMsg;
var errorSignIdentifier = "#" + inputField + " ." + errorSign;
if (inputField) {
$(fieldIdentifier).removeClass(" has-error has-feedback");
}
if (errorMsg) {
$(errorMsgIdentifier).addClass(" hidden");
}
if (errorSign) {
$(errorSignIdentifier).addClass(" hidden");
}
};
/**
* Checks if provided number is valid against a range.
*
* @param numberInput Number Input
* @param min Minimum Limit
* @param max Maximum Limit
* @returns {boolean} Returns true if input is within the specified range
*clear inline validation messages.
*/
var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
clearInline["policy-name"] = function () {
disableInlineError("policyNameField", "nameEmpty", "nameError");
};
/**
* Checks if provided input is valid against RegEx input.
*
* @param regExp Regular expression
* @param input Input string to check
* @returns {boolean} Returns true if input matches RegEx
* Validate if provided policy name is valid against RegEx configures.
*/
var inputIsValidAgainstRegExp = function (regExp, input) {
return regExp.test(input);
validateInline["policy-name"] = function () {
var policyName = $("input#policy-name-input").val();
if (policyName && inputIsValidAgainstLength(policyName, 1, 30)) {
disableInlineError("policyNameField", "nameEmpty", "nameError");
} else {
enableInlineError("policyNameField", "nameEmpty", "nameError");
}
};
validateStep["policy-profile"] = function () {
return true;
$("#policy-name-input").focus(function(){
clearInline["policy-name"]();
}).blur(function(){
validateInline["policy-name"]();
});
stepForwardFrom["policy-platform"] = function (actionButton) {
policy["platform"] = $(actionButton).data("platform");
policy["platformId"] = $(actionButton).data("platform-type");
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
var deviceType = policy["platform"];
var policyOperationsTemplateSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/templates/' + deviceType + '-policy-operations.hbs';
var policyOperationsScriptSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/js/' + deviceType + '-policy-operations.js';
var policyOperationsStylesSrc = context + '/public/cdmf.unit.device.type.' + deviceType +
'.policy-wizard/css/' + deviceType + '-policy-operations.css';
var policyOperationsTemplateCacheKey = deviceType + '-policy-operations';
$.isResourceExists(policyOperationsTemplateSrc, function (status) {
if (status) {
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) {
var content = template();
$(".wr-advance-operations").html(content);
$(".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);
}
});
$.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);
}
});
};
stepForwardFrom["policy-profile"] = function () {
policy["profile"] = operationModule.generateProfile(policy["platform"], configuredOperations);
// updating next-page wizard title with selected platform
$("#policy-criteria-page-wizard-title").text("ADD " + deviceTypeLabel + " POLICY");
$("#policy-criteria-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
};
stepBackFrom["policy-profile"] = function () {
@ -84,15 +143,13 @@ stepBackFrom["policy-profile"] = function () {
// so that, the wrong content would not be shown at the first glance, in case
// the user selects a different platform
$(".wr-advance-operations").html(
"<div class='wr-advance-operations-init'>" +
"<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
"<i class='fw fw-settings fw-spin fw-2x'></i>" +
"&nbsp;&nbsp;&nbsp;&nbsp;" +
"Loading Platform Features . . ." +
"<br>" +
"<br>" +
"</div>"
"<div class='wr-advance-operations-init'>" +
"<br>" +
"<i class='fw fw-settings fw-spin fw-2x'></i>" +
"Loading Platform Features . . ." +
"<br>" +
"<br>" +
"</div>"
);
};
@ -102,18 +159,18 @@ stepForwardFrom["policy-criteria"] = function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
policy["selectedUsers"] = $("#users-input").val();
policy["selectedUserRoles"] = null;
} else if ($(this).attr("id") == "user-roles-radio-btn") {
policy["selectedUsers"] = null;
policy["selectedUserRoles"] = $("#user-roles-input").val();
} else if ($(this).attr("id") == "groups-radio-btn") {
policy["selectedUserGroups"] = $("#groups-input").val();
}
}
}
});
policy["selectedNonCompliantAction"] = $("#action-input").find(":selected").data("action");
policy["selectedOwnership"] = $("#ownership-input").val();
// updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("ADD " + deviceTypeLabel + " POLICY");
//updating next-page wizard title with selected platform
$("#policy-naming-page-wizard-title").text("ADD " + policy["platform"] + " POLICY");
};
/**
@ -129,6 +186,44 @@ var inputIsValidAgainstLength = function (input, minLength, maxLength) {
return (length == minLength || (length > minLength && length < maxLength) || length == maxLength);
};
validateStep["policy-criteria"] = function () {
var validationStatus = {};
var selectedAssignees;
var selectedField = "Role(s)";
$("input[type='radio'].select-users-radio").each(function () {
if ($(this).is(":checked")) {
if ($(this).attr("id") == "users-radio-btn") {
selectedAssignees = $("#users-input").val();
selectedField = "User(s)";
} else if ($(this).attr("id") == "user-roles-radio-btn") {
selectedAssignees = $("#user-roles-input").val();
}
return false;
}
});
if (selectedAssignees) {
validationStatus["error"] = false;
} else {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] = selectedField + " is a required field. It cannot be empty";
}
var wizardIsToBeContinued;
if (validationStatus["error"]) {
wizardIsToBeContinued = false;
var mainErrorMsgWrapper = "#policy-criteria-main-error-msg";
var mainErrorMsg = mainErrorMsgWrapper + " span";
$(mainErrorMsg).text(validationStatus["mainErrorMsg"]);
$(mainErrorMsgWrapper).removeClass("hidden");
} else {
wizardIsToBeContinued = true;
}
return wizardIsToBeContinued;
};
validateStep["policy-naming"] = function () {
var validationStatus = {};
@ -141,7 +236,7 @@ validateStep["policy-naming"] = function () {
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length. Please check.";
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
@ -162,6 +257,10 @@ validateStep["policy-naming"] = function () {
return wizardIsToBeContinued;
};
validateStep["policy-platform"] = function () {
return false;
};
validateStep["policy-naming-publish"] = function () {
var validationStatus = {};
@ -174,7 +273,7 @@ validateStep["policy-naming-publish"] = function () {
} else if (!inputIsValidAgainstLength(policyName, 1, 30)) {
validationStatus["error"] = true;
validationStatus["mainErrorMsg"] =
"Policy name exceeds maximum allowed length. Please check.";
"Policy name exceeds maximum allowed length.";
} else {
validationStatus["error"] = false;
}
@ -199,34 +298,48 @@ stepForwardFrom["policy-naming-publish"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
savePolicy(policy, "publish");
savePolicy(policy, true, "/api/device-mgt/v1.0/policies/");
};
stepForwardFrom["policy-naming"] = function () {
policy["policyName"] = $("#policy-name-input").val();
policy["description"] = $("#policy-description-input").val();
//All data is collected. Policy can now be updated.
savePolicy(policy, "save");
savePolicy(policy, false, "/api/device-mgt/v1.0/policies/");
};
var savePolicy = function (policy, state) {
var profilePayloads = [{
"featureCode": "CONFIG",
"deviceTypeId": policy["platformId"],
"content": {"policyDefinition": window.queryEditor.getValue()}
}];
var savePolicy = function (policy, isActive, serviceURL) {
var profilePayloads = [];
// traverses key by key in policy["profile"]
var key;
for (key in policy["profile"]) {
if (policy["profile"].hasOwnProperty(key)) {
profilePayloads.push({
"featureCode": key,
"deviceType": policy["platform"],
"content": policy["profile"][key]
});
}
}
$.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;
}
});
});
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": "ANY",
"active": (state != "save"),
"ownershipType": policy["selectedOwnership"],
"active": isActive,
"profile": {
"profileName": policy["policyName"],
"deviceType": {
"id": policy["platformId"],
"name": policy["platform"]
},
"deviceType": policy["platform"],
"profileFeaturesList": profilePayloads
}
};
@ -241,101 +354,29 @@ var savePolicy = function (policy, state) {
}
invokerUtil.post(
"/api/device-mgt/v1.0/policies",
payload,
function (response) {
response = JSON.parse(response);
if (response["statusCode"] == 201) {
$(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden");
if (state == "publish") {
publishToDevice();
}
}
},
function (err) {
console.log(err);
}
);
};
function publishToDevice() {
var payload = {
"policyName": policy["policyName"],
"description": policy["description"],
"compliance": policy["selectedNonCompliantAction"],
"ownershipType": "ANY",
"deviceId": getParameterByName('deviceId'),
"profile": {
"profileName": policy["policyName"],
"deviceType": {
"id": policy["platformId"],
"name": policy["platform"]
},
"policyDefinition": window.queryEditor.getValue(),
"policyDescription": policy["description"]
}
};
var successCallback = function (data, status) {
console.log("Data: " + data + "\nStatus: " + status);
};
var data = {
url: "/devicemgt/api/policies/add",
type: "POST",
contentType: "application/json",
accept: "application/json",
success: successCallback,
data: JSON.stringify(payload)
};
$.ajax(data).fail(function (jqXHR) {
console.log("Error: " + jqXHR);
});
}
// Start of functions related to grid-input-view
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var setId = function (addFormContainer) {
$(addFormContainer).find("[data-add-form-clone]").each(function (i) {
$(this).attr("id", $(this).attr("data-add-form-clone").slice(1) + "-" + (i + 1));
if ($(this).find(".index").length > 0) {
$(this).find(".index").html(i + 1);
serviceURL,
payload,
function () {
$(".add-policy").addClass("hidden");
$(".policy-naming").addClass("hidden");
$(".policy-message").removeClass("hidden");
},
function (data) {
}
});
};
/**
* Method to set count id to cloned elements.
* @param {object} addFormContainer
*/
var showHideHelpText = function (addFormContainer) {
var helpText = "[data-help-text=add-form]";
if ($(addFormContainer).find("[data-add-form-clone]").length > 0) {
$(addFormContainer).find(helpText).hide();
} else {
$(addFormContainer).find(helpText).show();
}
);
};
function formatRepo(user) {
if (user.loading) {
return user.text
return user.text;
}
if (!user.username) {
return;
}
var markup = '<div class="clearfix">' +
'<div clas="col-sm-8">' +
'<div class="clearfix">' +
'<div class="col-sm-3">' + user.username + '</div>';
'<div clas="col-sm-8">' +
'<div class="clearfix">' +
'<div class="col-sm-3">' + user.username + '</div>';
if (user.firstname) {
markup += '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + user.firstname + '</div>';
}
@ -350,170 +391,74 @@ function formatRepoSelection(user) {
return user.username || user.text;
}
function formatGroupRepo(group) {
if (group.loading) {
return group.text
}
if (!group.name) {
return;
}
var markup = '<div class="clearfix">' +
'<div clas="col-sm-8">' +
'<div class="clearfix">' +
'<div class="col-sm-3">' + group.name + '</div>';
if (group.name) {
markup += '<div class="col-sm-3"><i class="fa fa-code-fork"></i> ' + group.name + '</div>';
}
if (group.owner) {
markup += '<div class="col-sm-2"><i class="fa fa-star"></i> ' + group.owner + '</div></div>';
}
markup += '</div></div>';
return markup;
}
function formatGroupRepoSelection(group) {
return group.name || group.text;
}
// End of functions related to grid-input-view
$(document).ready(function () {
window.queryEditor = CodeMirror.fromTextArea(document.getElementById('policy-definition-input'), {
mode: MIME_TYPE_SIDDHI_QL,
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
autofocus: true,
extraKeys: {
"Shift-2": function (cm) {
insertStr(cm, cm.getCursor(), '@');
CodeMirror.showHint(cm, getAnnotationHints);
$("#users-input").select2({
multiple: true,
tags: false,
ajax: {
url: context + "/api/invoker/execute/",
method: "POST",
dataType: 'json',
delay: 250,
id: function (user) {
return user.username;
},
"Ctrl-Space": "autocomplete"
}
data: function (params) {
var postData = {};
postData.requestMethod = "GET";
postData.requestURL = "/api/device-mgt/v1.0/users/search/usernames?filter=" + params.term;
postData.requestPayload = null;
return JSON.stringify(postData);
},
processResults: function (data) {
var newData = [];
$.each(data, function (index, value) {
value.id = value.username;
newData.push(value);
});
return {
results: newData
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
}, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
$("#users-input").select2({
multiple: true,
tags: true,
ajax: {
url: window.location.origin + "/devicemgt/api/invoker/execute/",
method: "POST",
dataType: 'json',
delay: 250,
id: function (user) {
return user.username;
},
data: function (params) {
var postData = {};
postData.actionMethod = "GET";
postData.actionUrl = "/devicemgt_admin/users";
postData.actionPayload = JSON.stringify({
q: params.term, // search term
page: params.page
});
return JSON.stringify(postData);
},
processResults: function (data, page) {
var newData = [];
$.each(data.responseContent, function (index, value) {
value.id = value.username;
newData.push(value);
});
return {
results: newData
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
}, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});
$("#groups-input").select2({
multiple: true,
tags: true,
ajax: {
url: window.location.origin + "/devicemgt/api/invoker/execute/",
method: "POST",
dataType: 'json',
delay: 250,
id: function (group) {
return group.name;
},
data: function (params) {
var postData = {};
postData.actionMethod = "GET";
var username = $("#platform").data("username");
postData.actionUrl = "/devicemgt_admin/groups/user/" + username +
"/search?groupName=" + params.term;
return JSON.stringify(postData);
},
processResults: function (data, page) {
var newData = [];
$.each(data, function (index, value) {
value.id = value.name;
newData.push(value);
});
return {
results: newData
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
}, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatGroupRepo, // omitted for brevity, see the source of this page
templateSelection: formatGroupRepoSelection // omitted for brevity, see the source of this page
});
$("#loading-content").remove();
$(".policy-platform").removeClass("hidden");
// Adding initial state of wizard-steps.
$("#policy-profile-wizard-steps").html($(".wr-steps").html());
policy["platform"] = $("#platform").data("platform");
policy["platformId"] = $("#platform").data("platform-id");
deviceTypeLabel = $("#platform").data("platform-label");
// updating next-page wizard title with selected platform
$("#policy-profile-page-wizard-title").text("ADD " + deviceTypeLabel + " POLICY");
$("#policy-platform-wizard-steps").html($(".wr-steps").html());
$("select.select2[multiple=multiple]").select2({
"tags": true
"tags": false
});
$("#users-select-field").hide();
$("#groups-select-field").hide();
$("#user-roles-select-field").show();
$("input[type='radio'].select-users-radio").change(function () {
if ($("#user-roles-radio-btn").is(":checked")) {
$("#user-roles-select-field").show();
$("#users-select-field").hide();
$("#groups-select-field").hide();
}
if ($("#users-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
$("#users-select-field").show();
$("#groups-select-field").hide();
}
if ($("#groups-radio-btn").is(":checked")) {
$("#user-roles-select-field").hide();
if ($("#user-roles-radio-btn").is(":checked")) {
$("#users-select-field").hide();
$("#groups-select-field").show();
$("#user-roles-select-field").show();
}
});
// Support for special input type "ANY" on user(s) & user-role(s) selection
$("#user-roles-input").select2({
"tags": true
"tags": false
}).on("select2:select", function (e) {
if (e.params.data.id == "ANY") {
$(this).val("ANY").trigger("change");
@ -522,152 +467,7 @@ $(document).ready(function () {
}
});
// Maintains an array of configured features of the profile
var advanceOperations = ".wr-advance-operations";
$(advanceOperations).on("click", ".wr-input-control.switch", function (event) {
var operationCode = $(this).parents(".operation-data").data("operation-code");
var operation = $(this).parents(".operation-data").data("operation");
var operationDataWrapper = $(this).data("target");
// prevents event bubbling by figuring out what element it's being called from.
if (event.target.tagName == "INPUT") {
var featureConfiguredIcon;
if ($("input[type='checkbox']", this).is(":checked")) {
configuredOperations.push(operationCode);
// when a feature is enabled, if "zero-configured-features" msg is available, hide that.
var zeroConfiguredOperationsErrorMsg = "#policy-profile-main-error-msg";
if (!$(zeroConfiguredOperationsErrorMsg).hasClass("hidden")) {
$(zeroConfiguredOperationsErrorMsg).addClass("hidden");
}
// add configured-state-icon to the feature
featureConfiguredIcon = "#" + operation + "-configured";
if ($(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).removeClass("hidden");
}
} else {
//splicing the array if operation is present.
var index = $.inArray(operationCode, configuredOperations);
if (index != -1) {
configuredOperations.splice(index, 1);
}
// when a feature is disabled, clearing all its current configured, error or success states
var subErrorMsgWrapper = "#" + operation + "-feature-error-msg";
var subErrorIcon = "#" + operation + "-error";
var subOkIcon = "#" + operation + "-ok";
featureConfiguredIcon = "#" + operation + "-configured";
if (!$(subErrorMsgWrapper).hasClass("hidden")) {
$(subErrorMsgWrapper).addClass("hidden");
}
if (!$(subErrorIcon).hasClass("hidden")) {
$(subErrorIcon).addClass("hidden");
}
if (!$(subOkIcon).hasClass("hidden")) {
$(subOkIcon).addClass("hidden");
}
if (!$(featureConfiguredIcon).hasClass("hidden")) {
$(featureConfiguredIcon).addClass("hidden");
}
// reinitializing input fields into the defaults
$(operationDataWrapper + " input").each(
function () {
if ($(this).is("input:text")) {
$(this).val($(this).data("default"));
} else if ($(this).is("input:password")) {
$(this).val("");
} else if ($(this).is("input:checkbox")) {
$(this).prop("checked", $(this).data("default"));
// if this checkbox is the parent input of a grouped-input
if ($(this).hasClass("parent-input")) {
var groupedInput = $(this).parent().parent().parent();
updateGroupedInputVisibility(groupedInput);
}
}
}
);
// reinitializing select fields into the defaults
$(operationDataWrapper + " select").each(
function () {
var defaultOption = $(this).data("default");
$("option:eq(" + defaultOption + ")", this).prop("selected", "selected");
}
);
// collapsing expanded-panes (upon the selection of html-select-options) if any
$(operationDataWrapper + " .expanded").each(
function () {
if ($(this).hasClass("expanded")) {
$(this).removeClass("expanded");
}
$(this).slideUp();
}
);
// removing all entries of grid-input elements if exist
$(operationDataWrapper + " .grouped-array-input").each(
function () {
var gridInputs = $(this).find("[data-add-form-clone]");
if (gridInputs.length > 0) {
gridInputs.remove();
}
var helpTexts = $(this).find("[data-help-text=add-form]");
if (helpTexts.length > 0) {
helpTexts.show();
}
}
);
}
}
});
// adding support for cloning multiple profiles per feature with cloneable class definitions
$(advanceOperations).on("click", ".multi-view.add.enabled", function () {
// get a copy of .cloneable and create new .cloned div element
var cloned = "<div class='cloned'><hr>" + $(".cloneable", $(this).parent().parent()).html() + "</div>";
// append newly created .cloned div element to panel-body
$(this).parent().parent().append(cloned);
// enable remove action of newly cloned div element
$(".cloned", $(this).parent().parent()).each(
function () {
if ($(".multi-view.remove", this).hasClass("disabled")) {
$(".multi-view.remove", this).removeClass("disabled");
}
if (!$(".multi-view.remove", this).hasClass("enabled")) {
$(".multi-view.remove", this).addClass("enabled");
}
}
);
});
$(advanceOperations).on("click", ".multi-view.remove.enabled", function () {
$(this).parent().remove();
});
// enabling or disabling grouped-input based on the status of a parent check-box
$(advanceOperations).on("click", ".grouped-input", function () {
updateGroupedInputVisibility(this);
});
// add form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=add-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
var clonedForm = $("[data-add-form=" + $(this).attr("href") + "]").clone().
find("[data-add-form-element=clone]").attr("data-add-form-clone", $(this).attr("href"));
// adding class .child-input to capture text-input-array-values
$("input, select", clonedForm).addClass("child-input");
$(addFormContainer).append(clonedForm);
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
// remove form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=remove-form]", function () {
var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]");
$(this).closest("[data-add-form-element=clone]").remove();
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
//Policy wizard stepper
$(".wizard-stepper").click(function () {
// button clicked here can be either a continue button or a back button.
var currentStep = $(this).data("current");
@ -685,11 +485,11 @@ $(document).ready(function () {
// remove if there are any visible error-messages.
var errorMsgWrappers = ".alert.alert-danger";
$(errorMsgWrappers).each(
function () {
if (!$(this).hasClass("hidden")) {
$(this).addClass("hidden");
}
function () {
if (!$(this).hasClass("hidden")) {
$(this).addClass("hidden");
}
}
);
var nextStep = $(this).data("next");
@ -728,16 +528,7 @@ $(document).ready(function () {
// hiding current section of the wizard and showing next section.
$("." + currentStep).addClass("hidden");
if (nextStep !== "policy-message") {
$("." + nextStep).removeClass("hidden");
}
$("." + nextStep).removeClass("hidden");
}
});
});
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
});

@ -1,47 +1,13 @@
{{#zone "topCss"}}
{{css "css/codemirror.css"}}
{{/zone}}
<span id="platform" class="hidden" data-platform="{{type.name}}" data-platform-id="{{type.id}}"
data-platform-label="{{type.label}}" data-username="{{username}}"></span>
<span id="platform" class="hidden" data-platform="{{type.name}}" data-platform-label="{{type.label}}"
data-username="{{username}}"></span>
<div class="row">
<div class="col-md-12">
<div class="wr-steps hidden">
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-platform">
<div class="wiz-no">1</div>
<div class="wiz-lbl hidden-xs"><span>Select a platform</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz itm-wiz-current" data-step="policy-profile">
<div class="wiz-no">2</div>
<div class="wiz-lbl hidden-xs"><span>Configure profile</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-criteria">
<div class="wiz-no">3</div>
<div class="wiz-lbl hidden-xs"><span>Assign</span></div>
</div>
<br class="c-both"/>
</div>
<div class="col-md-3 col-xs-3">
<div class="itm-wiz" data-step="policy-naming">
<div class="wiz-no">4</div>
<div class="wiz-lbl hidden-xs"><span>Publish to devices</span></div>
</div>
<br class="c-both"/>
</div>
</div>
<div class="container col-centered wr-content policy-message hidden">
<div class="wr-form">
<h1 id="policy-message-page-wizard-title" class="page-sub-title">Policy creation is
successful.</h1>
successful.</h1>
<br>Please click <b>"Add Another Policy"</b>, if you wish to add another policy or
click
click
<b>"View policy list"</b> to complete the process and go back to the policy list.
<hr>
<button class="wr-btn wizard-stepper" data-current="policy-message"
@ -247,18 +213,11 @@
<div class="col-lg-12">
<h4>Step 2: Configure profile</h4>
<br>
<label class="wr-input-label">
Set device specific configuration instructions
</label>
<div class="wr-advance-operations">
<div class="wr-input-control">
<div class="cus-col-100">
<textarea id="policy-definition-input" placeholder="Enter the policy"
style="width: 100%;" required></textarea>
</div>
<br class="c-both"/>
</div>
{{unit "cdmf.unit.device.type.generic.policy-wizard"}}
</div>
<div class="wr-input-control wr-btn-grp">
<a href="javascript:window.history.back()"
@ -281,7 +240,5 @@
</div>
</div>
{{#zone "bottomJs"}}
{{js "js/codemirror.js"}}
{{js "js/sql.js"}}
{{js "js/policy-create.js"}}
{{/zone}}

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

Loading…
Cancel
Save