resolving conflicts

merge-requests/7/head
thusithakalugamage 8 years ago
commit 6667a41378

@ -17,8 +17,7 @@ import javax.ws.rs.core.Response;
context = "api/certificate-mgt/v1.0/admin/certificates", context = "api/certificate-mgt/v1.0/admin/certificates",
tags = {"devicemgt_admin"}) tags = {"devicemgt_admin"})
@Api(value = "Certificate Management", description = "This API carries all certificate management related operations " + @Api(value = "Certificate Management", description = "This API includes all the certificate management related operations")
"such as get all the available devices, etc.")
@Path("/admin/certificates") @Path("/admin/certificates")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -36,14 +35,14 @@ public interface CertificateManagementAdminService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "POST", httpMethod = "POST",
value = "Add a SSL certificate", value = "Adding a new SSL certificate",
notes = "Add a new SSL certificate", notes = "Add a new SSL certificate to the client end database.\n",
tags = "Certificate Management") tags = "Certificate Management")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
code = 201, code = 201,
message = "Created. \n Certificates have successfully been added", message = "Created. \n Successfully added the certificate.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Location", name = "Content-Location",
@ -57,11 +56,11 @@ public interface CertificateManagementAdminService {
"Used by caches, or in conditional requests."), "Used by caches, or in conditional requests."),
@ResponseHeader( @ResponseHeader(
name = "Last-Modified", name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" + description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")}), "Used by caches, or in conditional requests.")}),
@ApiResponse( @ApiResponse(
code = 303, code = 303,
message = "See Other. \n Source can be retrieved from the URL specified at the Location header.", message = "See Other. \n The source can be retrieved from the URL specified in the location header.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Location", name = "Content-Location",
@ -72,7 +71,7 @@ public interface CertificateManagementAdminService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not supported format."), message = "Unsupported Media Type. \n The format of the requested entity was not supported."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n Server error occurred while adding certificates.", message = "Internal Server Error. \n Server error occurred while adding certificates.",
@ -82,8 +81,10 @@ public interface CertificateManagementAdminService {
Response addCertificate( Response addCertificate(
@ApiParam( @ApiParam(
name = "enrollmentCertificates", name = "enrollmentCertificates",
value = "certificate with serial, " value = "The properties to add a new certificate. It includes the following:\n" +
+ "pem and tenant id", "serial: The unique ID of the certificate.\n" +
"pem: Convert the OpenSSL certificate to the .pem format and base 64 encode the file.\n" +
"INFO: Upload the .pem file and base 64 encode it using a tool, such as the base64encode.in tool.",
required = true) EnrollmentCertificate[] enrollmentCertificates); required = true) EnrollmentCertificate[] enrollmentCertificates);
/** /**
@ -98,13 +99,13 @@ public interface CertificateManagementAdminService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Getting Details of an SSL CertificateManagementAdminService", value = "Getting Details of an SSL Certificate",
notes = "Get the client side SSL certificate details", notes = "Get the client side SSL certificate details.",
tags = "Certificate Management") tags = "Certificate Management")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Successfully fetched information of the device.", message = "OK. \n Successfully fetched the certificate details.",
response = CertificateResponse.class, response = CertificateResponse.class,
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
@ -116,7 +117,7 @@ public interface CertificateManagementAdminService {
"Used by caches, or in conditional requests."), "Used by caches, or in conditional requests."),
@ResponseHeader( @ResponseHeader(
name = "Last-Modified", name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" + description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."), "Used by caches, or in conditional requests."),
}), }),
@ApiResponse( @ApiResponse(
@ -129,22 +130,25 @@ public interface CertificateManagementAdminService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n No device is found under the provided type and id."), message = "Not Found. \n The specified certificate does not exist."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested certificate.", "Server error occurred while retrieving the requested certificate information.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "View certificates", permission = "/device-mgt/certificates/view") @Permission(name = "View certificates", permission = "/device-mgt/certificates/view")
Response getCertificate( Response getCertificate(
@ApiParam(name = "serialNumber", @ApiParam(name = "serialNumber",
value = "Provide the serial number of the certificate that you wish to get the details of", value = "The serial number of the certificate.",
required = true) required = true,
defaultValue = "124380353155528759302")
@PathParam("serialNumber") String serialNumber, @PathParam("serialNumber") String serialNumber,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Checks if the requested variant was modified, since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false) required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince @HeaderParam("If-Modified-Since") String ifModifiedSince
); );
@ -159,8 +163,8 @@ public interface CertificateManagementAdminService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Get certificates", value = "Getting Details of Certificates",
notes = "You will have many certificates used for mutual SSL. In a situation where you wish to " notes = "Get all the details of the certificates you have used for mutual SSL. In a situation where you wish to "
+ "view all the certificate details, it is not feasible to show all the details on one " + "view all the certificate details, it is not feasible to show all the details on one "
+ "page therefore the details are paginated", + "page therefore the details are paginated",
tags = "Certificate Management" tags = "Certificate Management"
@ -168,7 +172,7 @@ public interface CertificateManagementAdminService {
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n List of certificates enrolled in the system", message = "OK. \n Successfully fetched the list of certificates.",
response = CertificateList.class, response = CertificateList.class,
responseContainer = "List", responseContainer = "List",
responseHeaders = { responseHeaders = {
@ -181,12 +185,12 @@ public interface CertificateManagementAdminService {
"Used by caches, or in conditional requests."), "Used by caches, or in conditional requests."),
@ResponseHeader( @ResponseHeader(
name = "Last-Modified", name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" + description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")}), "Used by caches, or in conditional requests.")}),
@ApiResponse( @ApiResponse(
code = 303, code = 303,
message = "See Other. \n " + message = "See Other. \n " +
"Source can be retrieved from the URL specified at the Location header.", "The source can be retrieved from the URL specified in the location header.\n",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Location", name = "Content-Location",
@ -205,24 +209,28 @@ public interface CertificateManagementAdminService {
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n " +
"Server error occurred while retrieving all certificates enrolled in the system.", "Server error occurred while retrieving the certificate details.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "View certificates", permission = "/device-mgt/certificates/view") @Permission(name = "View certificates", permission = "/device-mgt/certificates/view")
Response getAllCertificates( Response getAllCertificates(
@ApiParam( @ApiParam(
name = "offset", name = "offset",
value = "Starting point within the complete list of items qualified.", value = "The starting pagination index for the complete list of qualified items",
required = false) required = false,
defaultValue = "0")
@QueryParam("offset") int offset, @QueryParam("offset") int offset,
@ApiParam( @ApiParam(
name = "limit", name = "limit",
value = "Maximum size of resource array to return.", value = "Provide how many certificate details you require from the starting pagination index/offset.",
required = false) required = false,
defaultValue = "5")
@QueryParam("limit") int limit, @QueryParam("limit") int limit,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Checks if the requested variant was modified, since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false) required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince); @HeaderParam("If-Modified-Since") String ifModifiedSince);
@ -232,20 +240,20 @@ public interface CertificateManagementAdminService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "DELETE", httpMethod = "DELETE",
value = "Delete an SSL certificate", value = "Deleting an SSL Certificate",
notes = "Delete an SSL certificate that's on the client end", notes = "Delete an SSL certificate that's on the client end",
tags = "Certificate Management") tags = "Certificate Management")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Certificate has successfully been removed"), message = "OK. \n Successfully removed the certificate."),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
message = "Bad Request. \n Invalid request or validation error.", message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Resource to be deleted does not exist."), message = "Not Found. \n The specified resource does not exist."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n " +
@ -255,9 +263,10 @@ public interface CertificateManagementAdminService {
Response removeCertificate( Response removeCertificate(
@ApiParam( @ApiParam(
name = "serialNumber", name = "serialNumber",
value = "Provide the serial number of the " value = "The serial number of the certificate.\n" +
+ "certificate that you wish to delete", "NOTE: Make sure that a certificate with the serial number you provide exists in the server. If no, first add a certificate.",
required = true) required = true,
defaultValue = "12438035315552875930")
@PathParam("serialNumber") String serialNumber); @PathParam("serialNumber") String serialNumber);
} }

@ -46,7 +46,7 @@ public interface ConfigurationManagementService {
httpMethod = "GET", httpMethod = "GET",
value = "Getting General Platform Configurations", value = "Getting General Platform Configurations",
notes = "WSO2 EMM monitors policies to verify that the devices comply with the policies enforced on them. " + notes = "WSO2 EMM monitors policies to verify that the devices comply with the policies enforced on them. " +
"General platform configurations include the settings on how often the the device need to be monitored. " + "General platform configurations include the settings on how often the device need to be monitored. " +
"Using this REST API you can get the general platform level configurations.", "Using this REST API you can get the general platform level configurations.",
tags = "Configuration Management") tags = "Configuration Management")
@ApiResponses( @ApiResponses(

@ -230,6 +230,72 @@ public interface DeviceManagementService {
@HeaderParam("If-Modified-Since") @HeaderParam("If-Modified-Since")
String ifModifiedSince); String ifModifiedSince);
//device delete request would looks like follows
//DELETE devices/type/virtual_firealarm/id/us06ww93auzp
@DELETE
@Path("/type/{device-type}/id/{device-id}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "DELETE",
value = "Delete the device speccified by device id",
notes = "Returns the status of the deleted device operation.",
tags = "Device Management")
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched information of the device.",
response = Device.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest " +
"version of the requested resource."),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n No device is found under the provided type and id.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving information requested device.",
response = ErrorResponse.class)
})
//TODO need to introduce delete permission
@Permission(name = "View Devices", permission = "/device-mgt/devices/owning-device/view")
Response deleteDevice(
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("device-type")
@Size(max = 45)
String deviceType,
@ApiParam(
name = "device-id",
value = "The device identifier of the device.",
required = true)
@PathParam("device-id")
@Size(max = 45)
String deviceId);
@GET @GET
@Path("/{type}/{id}/features") @Path("/{type}/{id}/features")
@ApiOperation( @ApiOperation(

@ -1,113 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "GroupManagement", version = "1.0.0", context = "/api/device-mgt/v1.0/groups", tags = {"device_management"})
@Path("/groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface GroupManagementService {
@GET
@Permission(name = "View Group", permission = "/permission/admin/device-mgt/user/groups/list")
Response getGroups(@QueryParam("user") String user, @QueryParam("offset") int offset,
@QueryParam("limit") int limit);
@POST
@Permission(name = "Add Group", permission = "/permission/admin/device-mgt/user/groups/add")
Response createGroup(DeviceGroup group);
@Path("/{groupName}")
@GET
@Permission(name = "View Group", permission = "/permission/admin/device-mgt/user/groups/view")
Response getGroup(@PathParam("groupName") String groupName);
@Path("/{groupName}")
@PUT
@Permission(name = "Update Group", permission = "/permission/admin/device-mgt/user/groups/update")
Response updateGroup(@PathParam("groupName") String groupName, DeviceGroup deviceGroup);
@Path("/{groupName}")
@DELETE
@Permission(name = "Remove Groups", permission = "/permission/admin/device-mgt/user/groups/remove")
Response deleteGroup(@PathParam("groupName") String groupName);
@Path("/{groupName}/share-with-user")
@POST
@Permission(name = "Share Group to a User", permission = "/permission/admin/device-mgt/user/groups/share")
Response shareGroupWithUser(@PathParam("groupName") String groupName, String targetUser);
@Path("/{groupName}/share-with-role")
@POST
@Permission(name = "Share Group to a Role", permission = "/permission/admin/device-mgt/user/groups/share")
Response shareGroupWithRole(@PathParam("groupName") String groupName, String targetRole);
@Path("/{groupName}/remove-share-with-user")
@POST
@Permission(name = "Unshare a Group", permission = "/permission/admin/device-mgt/user/groups/unshare")
Response removeShareWithUser(@PathParam("groupName") String groupName, String targetUser);
@Path("/{groupName}/remove-share-with-role")
@POST
@Permission(name = "Unshare a Group", permission = "/permission/admin/device-mgt/user/groups/unshare")
Response removeShareWithRole(@PathParam("groupName") String groupName, String targetUser);
@GET
@Path("/{groupName}/users")
@Permission(name = "Get Users of Group", permission = "/permission/admin/device-mgt/user/groups/list")
Response getUsersOfGroup(@PathParam("groupName") String groupName);
@GET
@Path("/{groupName}/devices")
@Permission(name = "Get Devices of Group", permission = "/permission/admin/device-mgt/groups/roles")
Response getDevicesOfGroup(@PathParam("groupName") String groupName, @QueryParam("offset") int offset,
@QueryParam("limit") int limit);
@POST
@Path("/{groupName}/devices")
@Produces("application/json")
@Permission(name = "Add Device to a Group", permission = "/permission/admin/device-mgt/user/groups/devices/add")
Response addDeviceToGroup(@PathParam("groupName") String groupName, DeviceIdentifier deviceIdentifier);
@DELETE
@Path("/{groupName}/devices")
@Permission(name = "Remove Devices from Group",
permission = "/permission/admin/device-mgt/user/groups/devices/remove")
Response removeDeviceFromGroup(@PathParam("groupName") String groupName, @QueryParam("type") String type,
@QueryParam("id") String id);
}

@ -79,7 +79,7 @@ public interface PolicyManagementService {
), ),
@ApiResponse( @ApiResponse(
code = 303, code = 303,
message = "See Other. \n he source can be retrieved from the URL specified in the location header", message = "See Other. \n The source can be retrieved from the URL specified in the location header",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Location", name = "Content-Location",
@ -106,8 +106,7 @@ public interface PolicyManagementService {
@ApiParam( @ApiParam(
name = "policy", name = "policy",
value = "The properties required to add a new policy.", value = "The properties required to add a new policy.",
required = true, required = true)
defaultValue = "{\"policyName\":\"test\",\"description\":\"test desc\",\"compliance\":\"ENFORCE\",\"ownershipType\":\"string\",\"active\":false,\"profile\":{\"profileId\":0,\"profileName\":\"string\",\"tenantId\":0,\"deviceType\":\"string\",\"createdDate\":\"2016-10-07T04:50:01.931Z\",\"updatedDate\":\"2016-10-07T04:50:01.931Z\",\"profileFeaturesList\":[{\"id\":0,\"featureCode\":\"string\",\"profileId\":0,\"deviceType\":\"string\",\"content\":{}}]},\"roles\":[\"string\"],\"deviceIdentifiers\":[{\"id\":\"string\",\"type\":\"string\"}],\"users\":[\"string\"]}")
@Valid PolicyWrapper policy); @Valid PolicyWrapper policy);
@GET @GET
@ -174,7 +173,7 @@ public interface PolicyManagementService {
int offset, int offset,
@ApiParam( @ApiParam(
name = "limit", name = "limit",
value = "Maximum size of resource array to return.", value = "Provide how many policy details you require from the starting pagination index/offset.",
required = false, required = false,
defaultValue = "5") defaultValue = "5")
@QueryParam("limit") @QueryParam("limit")
@ -427,7 +426,7 @@ public interface PolicyManagementService {
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT", httpMethod = "PUT",
value = "Applying Changes on Policies", value = "Applying Changes on Policies",
notes = "Policies in the active state will be applied to new device that register with WSO2 EMM based on" + notes = "Policies in the active state will be applied to new devices that register with WSO2 EMM based on" +
" the policy enforcement criteria . In a situation where you need to make changes to existing" + " the policy enforcement criteria . In a situation where you need to make changes to existing" +
" policies (removing, activating, deactivating and updating) or add new policies, the existing" + " policies (removing, activating, deactivating and updating) or add new policies, the existing" +
" devices will not receive these changes immediately. Once all the required changes are made" + " devices will not receive these changes immediately. Once all the required changes are made" +
@ -477,8 +476,7 @@ public interface PolicyManagementService {
@ApiParam( @ApiParam(
name = "priorityUpdatedPolicies", name = "priorityUpdatedPolicies",
value = "List of policies with priorities", value = "List of policies with priorities",
required = true, required = true)
defaultValue = "[{id:1,priority:2}]")
List<PriorityUpdatedPolicyWrapper> priorityUpdatedPolicies); List<PriorityUpdatedPolicyWrapper> priorityUpdatedPolicies);

@ -1,111 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api.admin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.ResponseHeader;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import org.wso2.carbon.policy.mgt.common.DeviceGroupWrapper;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@API(name = "GroupManagementAdmin", version = "1.0.0", context = "/api/device-mgt/v1.0/admin/groups", tags = {"device_management"})
@Path("/admin/groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Api(value = "Group Management Administrative Service", description = "This an API intended to be used by " +
"'internal' components to log in as an admin user and do a selected number of operations. " +
"Further, this is strictly restricted to admin users only ")
public interface GroupManagementAdminService {
@GET
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Grouping Devices",
notes = "Many devices can be registered with WSO2 IoTS. In order to manage them in an efficient manner, " +
"you can group devices and view the data gathered by the devices or share the groups with users so that they can monitor the devices in the respective group.",
response = DeviceGroupWrapper.class,
responseContainer = "List",
tags = "Group Management Administrative Service")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of groups.",
response = DeviceGroupWrapper.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the list of device groups.")
})
@Permission(name = "View All Groups", permission = "/permission/admin/device-mgt/user/groups/list")
Response getGroupsOfUser(
@ApiParam(
name = "username",
value = "The sername of the user.",
required = true)
@QueryParam("username") String username,
@ApiParam(
name = "If-Modified-Since",
value = "Timestamp of the last modified date",
required = false)
@HeaderParam("If-Modified-Since") String timestamp,
@ApiParam(
name = "offset",
value = "Starting point within the complete list of items qualified.",
required = false,
defaultValue = "0")
@QueryParam("offset") int offset,
@ApiParam(
name = "limit",
value = "Maximum size of resource array to return.",
required = false,
defaultValue = "5")
@QueryParam("limit") int limit);
}

@ -216,6 +216,20 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
} }
} }
@DELETE
@Override
@Path("/type/{device-type}/id/{device-id}")
public Response deleteDevice(@PathParam("device-type") String deviceType, @PathParam("device-id") String deviceId) {
log.info("Deleting " + deviceType + " " + deviceId + "is not supported");
try {
return Response.status(Response.Status.BAD_REQUEST).entity("{Deleting device(s) is not supported}").build();
} catch (Exception e) {
String msg = "Error occurred while deleting device(s)";
log.error(msg, e);
return Response.serverError().entity(new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@GET @GET
@Path("/{type}/{id}") @Path("/{type}/{id}")

@ -1,136 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.policy.mgt.common.DeviceGroupWrapper;
import javax.ws.rs.Consumes;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
@Path("/groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class GroupManagementServiceImpl implements GroupManagementService {
private static final Log log = LogFactory.getLog(GroupManagementServiceImpl.class);
@Override
public Response getGroups(@QueryParam("user") String user, @QueryParam("offset") int offset,
@QueryParam("limit") int limit) {
try {
List<DeviceGroupWrapper> groupWrappers = new ArrayList<>();
GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService();
List<DeviceGroup> deviceGroups = service.getGroups(user);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
for (DeviceGroup dg : deviceGroups) {
DeviceGroupWrapper gw = new DeviceGroupWrapper();
gw.setId(dg.getId());
gw.setOwner(dg.getOwner());
gw.setName(dg.getName());
gw.setTenantId(tenantId);
groupWrappers.add(gw);
}
return Response.status(Response.Status.OK).entity(groupWrappers).build();
} catch (GroupManagementException e) {
String error = "ErrorResponse occurred while getting the groups related to users for policy.";
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Override
public Response createGroup(DeviceGroup group) {
return null;
}
@Override
public Response getGroup(@PathParam("groupName") String groupName) {
return null;
}
@Override
public Response updateGroup(@PathParam("groupName") String groupName, DeviceGroup deviceGroup) {
return null;
}
@Override
public Response deleteGroup(@PathParam("groupName") String groupName) {
return null;
}
@Override
public Response shareGroupWithUser(String groupName, String targetUser) {
return null;
}
@Override
public Response shareGroupWithRole(String groupName, String targetRole) {
return null;
}
@Override
public Response removeShareWithUser(@PathParam("groupName") String groupName,
@QueryParam("username") String targetUser) {
return null;
}
@Override
public Response removeShareWithRole(@PathParam("groupName") String groupName,
@QueryParam("roleName") String targetUser) {
return null;
}
@Override
public Response getUsersOfGroup(@PathParam("groupName") String groupName) {
return null;
}
@Override
public Response getDevicesOfGroup(@PathParam("groupName") String groupName, @QueryParam("offset") int offset,
@QueryParam("limit") int limit) {
return null;
}
@Override
public Response addDeviceToGroup(@PathParam("groupName") String groupName, DeviceIdentifier deviceIdentifier) {
return null;
}
@Override
public Response removeDeviceFromGroup(@PathParam("groupName") String groupName, @QueryParam("type") String type,
@QueryParam("id") String id) {
return null;
}
}

@ -135,7 +135,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
final UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore); final UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore);
final UIPermissionNode rolePermissions = final UIPermissionNode rolePermissions =
userRealmProxy.getRolePermissions(roleName, MultitenantConstants.SUPER_TENANT_ID); userRealmProxy.getRolePermissions(roleName, MultitenantConstants.SUPER_TENANT_ID);
UIPermissionNode[] deviceMgtPermissions = new UIPermissionNode[2]; UIPermissionNode[] deviceMgtPermissions = new UIPermissionNode[4];
for (UIPermissionNode permissionNode : rolePermissions.getNodeList()) { for (UIPermissionNode permissionNode : rolePermissions.getNodeList()) {
if (permissionNode.getResourcePath().equals("/permission/admin")) { if (permissionNode.getResourcePath().equals("/permission/admin")) {
@ -144,6 +144,15 @@ public class RoleManagementServiceImpl implements RoleManagementService {
deviceMgtPermissions[0] = node; deviceMgtPermissions[0] = node;
} else if (node.getResourcePath().equals("/permission/admin/login")) { } else if (node.getResourcePath().equals("/permission/admin/login")) {
deviceMgtPermissions[1] = node; deviceMgtPermissions[1] = node;
} else if (node.getResourcePath().equals("/permission/admin/manage")) {
// Adding permissions related to app-store in emm-console
for (UIPermissionNode subNode : node.getNodeList()) {
if (subNode.getResourcePath().equals("/permission/admin/manage/mobileapp")) {
deviceMgtPermissions[2] = subNode;
} else if (subNode.getResourcePath().equals("/permission/admin/manage/webapp")) {
deviceMgtPermissions[3] = subNode;
}
}
} }
} }
} }

@ -1,66 +0,0 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.GroupManagementAdminService;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/admin/groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class GroupManagementAdminServiceImpl implements GroupManagementAdminService {
private static final Log log = LogFactory.getLog(GroupManagementAdminServiceImpl.class);
@GET
@Override
public Response getGroupsOfUser(
@QueryParam("username") String username,
@HeaderParam("If-Modified-Since") String timestamp,
@QueryParam("offset") int offset,
@QueryParam("limit") int limit) {
try {
PaginationResult result =
DeviceMgtAPIUtils.getGroupManagementProviderService().getGroups(username, offset, limit);
if (result != null && result.getRecordsTotal() > 0) {
return Response.status(Response.Status.OK).entity(result).build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
} catch (GroupManagementException e) {
String msg = "ErrorResponse occurred while retrieving the groups of user '" + username + "'";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
}

@ -337,10 +337,10 @@ public class RequestValidationUtil {
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit is a " + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit is a " +
"negative value.").build()); "negative value.").build());
} }
if (limit - offset > 100) { if (limit > 100) {
throw new InputValidationException( throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request results list should" + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit should" +
" be less than or equal 100 values.").build()); " be less than or equal to 100.").build());
} }
} }

@ -35,7 +35,7 @@
<ref bean="userManagementService"/> <ref bean="userManagementService"/>
<ref bean="userManagementAdminService"/> <ref bean="userManagementAdminService"/>
<!--<ref bean="groupManagementService"/>--> <!--<ref bean="groupManagementService"/>-->
<ref bean="groupManagementAdminService"/> <!--ref bean="groupManagementAdminService"/> -->
<ref bean="applicationManagementAdminService"/> <ref bean="applicationManagementAdminService"/>
<ref bean="deviceTypeManagementAdminService"/> <ref bean="deviceTypeManagementAdminService"/>
<ref bean="dashboardServiceBean"/> <ref bean="dashboardServiceBean"/>
@ -73,10 +73,10 @@
<bean id="policyManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.PolicyManagementServiceImpl"/> <bean id="policyManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.PolicyManagementServiceImpl"/>
<bean id="roleManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.RoleManagementServiceImpl"/> <bean id="roleManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.RoleManagementServiceImpl"/>
<bean id="userManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.UserManagementServiceImpl"/> <bean id="userManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.UserManagementServiceImpl"/>
<bean id="groupManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.GroupManagementServiceImpl"/> <!--bean id="groupManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.GroupManagementServiceImpl"/>-->
<bean id="deviceManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceManagementAdminServiceImpl"/> <bean id="deviceManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceManagementAdminServiceImpl"/>
<bean id="applicationManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.ApplicationManagementAdminServiceImpl"/> <bean id="applicationManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.ApplicationManagementAdminServiceImpl"/>
<bean id="groupManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.GroupManagementAdminServiceImpl"/> <!--bean id="groupManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.GroupManagementAdminServiceImpl"/>-->
<bean id="userManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.UserManagementAdminServiceImpl"/> <bean id="userManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.UserManagementAdminServiceImpl"/>
<bean id="dashboardServiceBean" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DashboardImpl"/> <bean id="dashboardServiceBean" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DashboardImpl"/>
<bean id="deviceTypeManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceTypeManagementServiceImpl"/> <bean id="deviceTypeManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.DeviceTypeManagementServiceImpl"/>

@ -19,7 +19,9 @@
package org.wso2.carbon.device.mgt.core.config.policy; package org.wso2.carbon.device.mgt.core.config.policy;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlRootElement(name = "PolicyConfiguration") @XmlRootElement(name = "PolicyConfiguration")
public class PolicyConfiguration { public class PolicyConfiguration {
@ -30,6 +32,7 @@ public class PolicyConfiguration {
private int maxRetries; private int maxRetries;
private int minRetriesToMarkUnreachable; private int minRetriesToMarkUnreachable;
private int minRetriesToMarkInactive; private int minRetriesToMarkInactive;
private List<String> platforms;
@XmlElement(name = "MonitoringClass", required = true) @XmlElement(name = "MonitoringClass", required = true)
public String getMonitoringClass() { public String getMonitoringClass() {
@ -85,4 +88,14 @@ public class PolicyConfiguration {
this.monitoringFrequency = monitoringFrequency; this.monitoringFrequency = monitoringFrequency;
} }
@XmlElementWrapper(name = "Platforms", required = true)
@XmlElement(name = "Platform", required = true)
public List<String> getPlatforms() {
return platforms;
}
public void setPlatforms(List<String> platforms) {
this.platforms = platforms;
}
} }

@ -39,7 +39,7 @@ var userModule = function () {
* Get the carbon user object from the session. If not found - it will throw a user not found error. * Get the carbon user object from the session. If not found - it will throw a user not found error.
* @returns {object} carbon user object * @returns {object} carbon user object
*/ */
privateMethods.getCarbonUser = function () { publicMethods.getCarbonUser = function () {
var carbon = require("carbon"); var carbon = require("carbon");
var carbonUser = session.get(constants["USER_SESSION_KEY"]); var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"]; var utility = require("/app/modules/utility.js")["utility"];
@ -59,17 +59,17 @@ var userModule = function () {
privateMethods.callBackend = function (url, method) { privateMethods.callBackend = function (url, method) {
if (constants["HTTP_GET"] == method) { if (constants["HTTP_GET"] == method) {
return serviceInvokers.XMLHttp.get(url, return serviceInvokers.XMLHttp.get(url,
function (backendResponse) { function (backendResponse) {
var response = {}; var response = {};
response.content = backendResponse.responseText; response.content = backendResponse.responseText;
if (backendResponse.status == 200) { if (backendResponse.status == 200) {
response.status = "success"; response.status = "success";
} else if (backendResponse.status == 400 || backendResponse.status == 401 || } else if (backendResponse.status == 400 || backendResponse.status == 401 ||
backendResponse.status == 404 || backendResponse.status == 500) { backendResponse.status == 404 || backendResponse.status == 500) {
response.status = "error"; response.status = "error";
} }
return response; return response;
} }
); );
} else { } else {
log.error("Runtime error : This method only support HTTP GET requests."); log.error("Runtime error : This method only support HTTP GET requests.");
@ -176,7 +176,7 @@ var userModule = function () {
* @returns {object} a response object with status and content on success. * @returns {object} a response object with status and content on success.
*/ */
publicMethods.getUser = function (username) { publicMethods.getUser = function (username) {
var carbonUser = privateMethods.getCarbonUser(); var carbonUser = publicMethods.getCarbonUser();
var domain; var domain;
if (username.indexOf('/') > 0) { if (username.indexOf('/') > 0) {
domain = username.substr(0, username.indexOf('/')); domain = username.substr(0, username.indexOf('/'));
@ -185,7 +185,7 @@ var userModule = function () {
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
encodeURIComponent(username); encodeURIComponent(username);
if (domain) { if (domain) {
url += '?domain=' + domain; url += '?domain=' + domain;
} }
@ -206,7 +206,7 @@ var userModule = function () {
* @returns {object} a response object with status and content on success. * @returns {object} a response object with status and content on success.
*/ */
publicMethods.getRolesByUsername = function (username) { publicMethods.getRolesByUsername = function (username) {
var carbonUser = privateMethods.getCarbonUser(); var carbonUser = publicMethods.getCarbonUser();
var domain; var domain;
if (username.indexOf('/') > 0) { if (username.indexOf('/') > 0) {
domain = username.substr(0, username.indexOf('/')); domain = username.substr(0, username.indexOf('/'));
@ -215,7 +215,7 @@ var userModule = function () {
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
encodeURIComponent(username) + "/roles"; encodeURIComponent(username) + "/roles";
if (domain) { if (domain) {
url += '?domain=' + domain; url += '?domain=' + domain;
} }
@ -268,7 +268,7 @@ var userModule = function () {
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles?offset=0&limit=100"; "/roles?offset=0&limit=100";
var response = privateMethods.callBackend(url, constants["HTTP_GET"]); var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") { if (response.status == "success") {
response.content = parse(response.content).roles; response.content = parse(response.content).roles;
@ -294,7 +294,7 @@ var userModule = function () {
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles?offset=0&limit=1"; "/roles?offset=0&limit=1";
return serviceInvokers.XMLHttp.get( return serviceInvokers.XMLHttp.get(
url, function (responsePayload) { url, function (responsePayload) {
return parse(responsePayload["responseText"])["count"]; return parse(responsePayload["responseText"])["count"];
@ -328,7 +328,7 @@ var userModule = function () {
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles?user-store=" + userStore + "&limit=100"; "/roles?user-store=" + userStore + "&limit=100";
var response = privateMethods.callBackend(url, constants["HTTP_GET"]); var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") { if (response.status == "success") {
response.content = parse(response.content).roles; response.content = parse(response.content).roles;
@ -381,7 +381,7 @@ var userModule = function () {
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles/" + encodeURIComponent(roleName); "/roles/" + encodeURIComponent(roleName);
var response = privateMethods.callBackend(url, constants["HTTP_GET"]); var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") { if (response.status == "success") {
response.content = parse(response.content); response.content = parse(response.content);

@ -90,34 +90,48 @@ $("a#invite-user-link").click(function () {
var inviteUserAPI = apiBasePath + "/users/send-invitation"; var inviteUserAPI = apiBasePath + "/users/send-invitation";
if (usernameList.length == 0) { if (usernameList.length == 0) {
$(modalPopupContent).html($("#errorUsers").html()); modalDialog.header("Operation cannot be performed !");
modalDialog.content("Please select a user or a list of users to send invitation emails.");
modalDialog.footer('<div class="buttons"> <a href="javascript:modalDialog.hide()" class="btn-operations">Ok' +
'</a> </div>');
modalDialog.showAsError();
} else { } else {
$(modalPopupContent).html($('#invite-user-modal-content').html()); modalDialog.header("");
} modalDialog.content("An invitation mail will be sent to the selected user(s) to initiate an enrolment process." +
" Do you wish to continue ?");
modalDialog.footer('<div class="buttons"> <a href="#" id="invite-user-yes-link" class="btn-operations">yes</a>' +
'<a href="#" id="invite-user-cancel-link" class="btn-operations btn-default">No</a> </div>');
modalDialog.show();
showPopup(); }
$("a#invite-user-yes-link").click(function () { $("a#invite-user-yes-link").click(function () {
invokerUtil.post( invokerUtil.post(
inviteUserAPI, inviteUserAPI,
usernameList, usernameList,
function () { function () {
$(modalPopupContent).html($('#invite-user-success-content').html()); modalDialog.header("User invitation email for enrollment was successfully sent.");
modalDialog.footer('<div class="buttons"> <a href="#" id="invite-user-success-link" ' +
'class="btn-operations">Ok </a> </div>');
$("a#invite-user-success-link").click(function () { $("a#invite-user-success-link").click(function () {
hidePopup(); modalPopup.hide();
}); });
}, },
function () { function () {
$(modalPopupContent).html($('#invite-user-error-content').html()); modalDialog.header('<span class="fw-stack"> <i class="fw fw-ring fw-stack-2x"></i> <i class="fw ' +
'fw-error fw-stack-1x"></i> </span> Unexpected Error !');
modalDialog.content('An unexpected error occurred. Try again later.');
modalDialog.footer('<div class="buttons"> <a href="#" id="invite-user-error-link" ' +
'class="btn-operations">Ok </a> </div>');
$("a#invite-user-error-link").click(function () { $("a#invite-user-error-link").click(function () {
hidePopup(); modalPopup.hide();
}); });
} }
); );
}); });
$("a#invite-user-cancel-link").click(function () { $("a#invite-user-cancel-link").click(function () {
hidePopup(); modalPopup.hide();
}); });
}); });
@ -139,13 +153,16 @@ function getSelectedUsernames() {
* on User Listing page in WSO2 MDM Console. * on User Listing page in WSO2 MDM Console.
*/ */
function resetPassword(username) { function resetPassword(username) {
$(modalPopupContent).html($('#reset-password-window').html()); modalDialog.header('<span class="fw-stack"> <i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-key ' +
showPopup(); 'fw-stack-1x"></i> </span> Reset Password');
modalDialog.content($("#modal-content-reset-password").html());
modalDialog.footer('<div class="buttons"> <a href="#" id="reset-password-yes-link" class="btn-operations"> Save ' +
'</a> <a href="#" id="reset-password-cancel-link" class="btn-operations btn-default"> Cancel </a> </div>');
modalDialog.show();
$("a#reset-password-yes-link").click(function () { $("a#reset-password-yes-link").click(function () {
var newPassword = $("#new-password").val(); var newPassword = $("#basic-modal-view .new-password").val();
var confirmedPassword = $("#confirmed-password").val(); var confirmedPassword = $("#basic-modal-view .confirmed-password").val();
var errorMsgWrapper = "#notification-error-msg"; var errorMsgWrapper = "#notification-error-msg";
var errorMsg = "#notification-error-msg span"; var errorMsg = "#notification-error-msg span";
if (!newPassword) { if (!newPassword) {
@ -178,10 +195,10 @@ function resetPassword(username) {
// The success callback // The success callback
function (data, textStatus, jqXHR) { function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) { if (jqXHR.status == 200) {
$(modalPopupContent).html($('#reset-password-success-content').html()); modalDialog.header("Password reset is successful.");
$("a#reset-password-success-link").click(function () { modalDialog.content("");
hidePopup(); modalDialog.footer('<div class="buttons"> <a href="javascript:modalDialog.hide()" ' +
}); 'class="btn-operations">Ok</a> </div>');
} }
}, },
// The error callback // The error callback
@ -195,7 +212,7 @@ function resetPassword(username) {
}); });
$("a#reset-password-cancel-link").click(function () { $("a#reset-password-cancel-link").click(function () {
hidePopup(); modalDialog.hide();
}); });
} }
@ -214,8 +231,16 @@ function removeUser(username) {
if (domain) { if (domain) {
removeUserAPI += '?domain=' + domain; removeUserAPI += '?domain=' + domain;
} }
$(modalPopupContent).html($('#remove-user-modal-content').html());
showPopup(); modalDialog.header("Remove User");
modalDialog.content("Do you really want to remove this user ?");
modalDialog.footer('<div class="buttons"> <a href="#" id="remove-user-yes-link" class="btn-operations">Remove</a> ' +
'<a href="#" id="remove-user-cancel-link" class="btn-operations btn-default">Cancel</a> </div>');
modalDialog.showAsAWarning();
$("a#remove-user-cancel-link").click(function () {
modalDialog.hide();
});
$("a#remove-user-yes-link").click(function () { $("a#remove-user-yes-link").click(function () {
invokerUtil.delete( invokerUtil.delete(
@ -228,17 +253,20 @@ function removeUser(username) {
$("#user-" + username).remove(); $("#user-" + username).remove();
} }
// update modal-content with success message // update modal-content with success message
$(modalPopupContent).html($('#remove-user-success-content').html()); modalDialog.header("User Removed.");
$("a#remove-user-success-link").click(function () { modalDialog.content("Done. User was successfully removed.");
hidePopup(); modalDialog.footer('<div class="buttons"> <a href="javascript:modalDialog.hide()" ' +
}); 'class="btn-operations">Ok</a> </div>');
} }
}, },
function () { function () {
$(modalPopupContent).html($('#remove-user-error-content').html()); modalDialog.hide();
$("a#remove-user-error-link").click(function () { modalDialog.header("Operation cannot be performed !");
hidePopup(); modalDialog.content("An unexpected error occurred. Please try again later.");
}); modalDialog.footer('<div class="buttons"> <a href="javascript:modalDialog.hide()" ' +
'class="btn-operations">Ok</a> </div>');
modalDialog.showAsError();
} }
); );
}); });
@ -257,8 +285,10 @@ function InitiateViewOption() {
if ($("#can-view").val()) { if ($("#can-view").val()) {
$(location).attr('href', $(this).data("url")); $(location).attr('href', $(this).data("url"));
} else { } else {
$(modalPopupContent).html($('#errorUserView').html()); modalDialog.header("Unauthorized action!");
showPopup(); modalDialog.content("You don't have permissions to view users");
modalDialog.footer('<div class="buttons"> <a href="javascript:modalDialog.hide()" class="btn-operations">Ok</a> </div>');
modalDialog.showAsError();
} }
} }
@ -314,7 +344,7 @@ function loadUsers() {
if (!data.firstname && !data.lastname) { if (!data.firstname && !data.lastname) {
return ""; return "";
} else if (data.firstname && data.lastname) { } else if (data.firstname && data.lastname) {
return "<h4>&nbsp;&nbsp;" + data.firstname + " " + data.lastname + "</h4>"; return "<h4>" + data.firstname + " " + data.lastname + "</h4>";
} }
} }
}, },
@ -322,7 +352,7 @@ function loadUsers() {
class: "fade-edge remove-padding-top", class: "fade-edge remove-padding-top",
data: 'filter', data: 'filter',
render: function (filter, type, row, meta) { render: function (filter, type, row, meta) {
return '&nbsp;&nbsp;<i class="fw-user"></i>&nbsp;&nbsp;' + filter; return '<i class="fw-user"></i>' + filter;
} }
}, },
{ {
@ -332,7 +362,7 @@ function loadUsers() {
if (!data.emailAddress) { if (!data.emailAddress) {
return ""; return "";
} else { } else {
return "&nbsp;&nbsp;<a href='mailto:" + data.emailAddress + "' ><i class='fw-mail'></i>&nbsp;&nbsp;" + data.emailAddress + "</a>"; return "<a href='mailto:" + data.emailAddress + "' ><i class='fw-mail'></i>" + data.emailAddress + "</a>";
} }
} }
}, },
@ -340,17 +370,13 @@ function loadUsers() {
class: "text-right content-fill text-left-on-grid-view no-wrap", class: "text-right content-fill text-left-on-grid-view no-wrap",
data: null, data: null,
render: function (data, type, row, meta) { render: function (data, type, row, meta) {
var editbtn = '&nbsp;<a data-toggle="tooltip" data-placement="bottom" title="Edit User"href="' + context + '/user/edit?username=' + data.filter + '" data-username="' + data.filter + '" ' + var editbtn = '<a data-toggle="tooltip" data-placement="bottom" title="Edit User"href="' + context + '/user/edit?username=' + data.filter + '" data-username="' + data.filter + '" ' +
'data-click-event="edit-form" ' + 'data-click-event="edit-form" ' +
'class="btn padding-reduce-on-grid-view edit-user-link"> ' + 'class="btn padding-reduce-on-grid-view edit-user-link"> ' +
'<span class="fw-stack"> ' + '<span class="fw-stack"> ' +
'<i class="fw fw-ring fw-stack-2x"></i>' + '<i class="fw fw-ring fw-stack-2x"></i>' +
'<i class="fw fw-edit fw-stack-1x"></i>' + '<i class="fw fw-edit fw-stack-1x"></i>' +
'</span>' + '</span><span class="hidden-xs hidden-on-grid-view">Edit</span></a>';
'<span class="hidden-xs hidden-on-grid-view">' +
'&nbsp;&nbsp;Edit' +
'</span>' +
'</a>';
var resetPasswordbtn = '<a data-toggle="tooltip" data-placement="bottom" title="Reset Password" href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' + var resetPasswordbtn = '<a data-toggle="tooltip" data-placement="bottom" title="Reset Password" href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' +
'data-click-event="edit-form" ' + 'data-click-event="edit-form" ' +
@ -359,11 +385,7 @@ function loadUsers() {
'<span class="fw-stack">' + '<span class="fw-stack">' +
'<i class="fw fw-ring fw-stack-2x"></i>' + '<i class="fw fw-ring fw-stack-2x"></i>' +
'<i class="fw fw-key fw-stack-1x"></i>' + '<i class="fw fw-key fw-stack-1x"></i>' +
'</span>' + '</span><span class="hidden-xs hidden-on-grid-view">Reset Password</span></a>';
'<span class="hidden-xs hidden-on-grid-view">' +
'&nbsp;&nbsp;Reset Password' +
'</span>' +
'</a>';
var removebtn = '<a data-toggle="tooltip" data-placement="bottom" title="Remove User" href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' + var removebtn = '<a data-toggle="tooltip" data-placement="bottom" title="Remove User" href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' +
'data-click-event="remove-form" ' + 'data-click-event="remove-form" ' +
@ -372,20 +394,18 @@ function loadUsers() {
'<span class="fw-stack">' + '<span class="fw-stack">' +
'<i class="fw fw-ring fw-stack-2x"></i>' + '<i class="fw fw-ring fw-stack-2x"></i>' +
'<i class="fw fw-delete fw-stack-1x"></i>' + '<i class="fw fw-delete fw-stack-1x"></i>' +
'</span>' + '</span><span class="hidden-xs hidden-on-grid-view">Remove</span></a>';
'<span class="hidden-xs hidden-on-grid-view">' +
'&nbsp;&nbsp;Remove' +
'</span>' +
'</a>';
var returnbtnSet = ''; var returnbtnSet = '';
if ($("#can-edit").length > 0) { var adminUser = $("#user-table").data("user");
var currentUser = $("#user-table").data("logged-user");
if ($("#can-edit").length > 0 && adminUser !== data.filter) {
returnbtnSet = returnbtnSet + editbtn; returnbtnSet = returnbtnSet + editbtn;
} }
if ($("#can-reset-password").length > 0) { if ($("#can-reset-password").length > 0 && adminUser !== data.filter) {
returnbtnSet = returnbtnSet + resetPasswordbtn; returnbtnSet = returnbtnSet + resetPasswordbtn;
} }
if ($("#can-remove").length > 0) { if ($("#can-remove").length > 0 && adminUser !== data.filter && currentUser !== data.filter) {
returnbtnSet = returnbtnSet + removebtn; returnbtnSet = returnbtnSet + removebtn;
} }

@ -18,6 +18,7 @@
{{unit "cdmf.unit.ui.title" pageTitle="User Management"}} {{unit "cdmf.unit.ui.title" pageTitle="User Management"}}
{{unit "cdmf.unit.data-tables-extended"}} {{unit "cdmf.unit.data-tables-extended"}}
{{unit "cdmf.unit.ui.modal"}}
{{#zone "breadcrumbs"}} {{#zone "breadcrumbs"}}
<li> <li>
@ -47,7 +48,7 @@
{{/zone}} {{/zone}}
{{#zone "content"}} {{#zone "content"}}
<input type="hidden" id="user" value="{{user.username}}">
<!-- content --> <!-- content -->
<div id="loading-content" class="col-centered"> <div id="loading-content" class="col-centered">
{{#if canManage}} {{#if canManage}}
@ -65,7 +66,7 @@
<br> <br>
</div> </div>
<div id="user-table" data-user={{adminUser}}> <div id="user-table" data-user={{adminUser}} data-logged-user={{currentUser}}>
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view" <table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view"
id="user-grid"> id="user-grid">
<thead> <thead>
@ -99,226 +100,26 @@
</div> </div>
</div> </div>
<div id="invite-user-modal-content" class="hide"> <div id="modal-content-reset-password" class="hide">
<div class="modal-header"> <div id="notification-error-msg" class="alert alert-danger hidden" role="alert">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i> <i class="icon fw fw-error"></i><span></span>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
An invitation mail will be sent to the selected user(s) to initiate an enrolment process.
Do you wish to continue ?
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="invite-user-yes-link" class="btn-operations">yes</a>
<a href="#" id="invite-user-cancel-link" class="btn-operations btn-default">No</a>
</div>
</div>
</div>
<div id="invite-user-success-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">User invitation email for enrollment was successfully sent.</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i></button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="invite-user-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div>
<div id="invite-user-error-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Unexpected Error
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
An unexpected error occurred. Try again later.
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="invite-user-error-link" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="remove-user-modal-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
Remove User
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
Do you really want to remove this user ?
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="remove-user-yes-link" class="btn-operations">Remove</a>
<a href="#" id="remove-user-cancel-link" class="btn-operations btn-default">Cancel</a>
</div>
</div>
</div>
<div id="remove-user-success-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
User Removed.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
Done. User was successfully removed.
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="remove-user-success-link" class="btn-operations">Ok</a>
</div>
</div>
</div>
<div id="remove-user-error-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Unexpected Error
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div> </div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x"> <h4>
<h4> Enter new password
An unexpected error occurred. Please try again later. <br><br>
</h4> <div>
</div> <input type="password" class="form-control modal-input operationDataKeys new-password"
<div class="modal-footer"> data-key="message"/>
<div class="buttons">
<a href="#" id="remove-user-error-link" class="btn-operations">Ok</a>
</div> </div>
</div> <br>
</div> Retype new password
<br><br>
<div id="errorUsers" class="hide"> <div>
<div class="modal-header"> <input type="password" class="form-control modal-input operationDataKeys confirmed-password"
<h3 class="pull-left modal-title"> data-key="message"/>
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
Operation cannot be performed !
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4>
Please select a user or a list of users to send invitation emails.
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div> </div>
</div> <br>
</div> </h4>
<div id="errorUserView" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
Unauthorized action!
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
</div>
<div id="reset-password-window" class="hide">
<input type="hidden" id="user" value="{{user.username}}">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-key fw-stack-1x"></i>
</span>
Reset Password
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<div id="notification-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<h4>
Enter new password
<br><br>
<div>
<input type="password" class="form-control modal-input operationDataKeys" id="new-password"
data-key="message"/>
</div>
<br>
Retype new password
<br><br>
<div>
<input type="password" class="form-control modal-input operationDataKeys" id="confirmed-password"
data-key="message"/>
</div>
<br>
</h4>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="reset-password-yes-link" class="btn-operations">
Save
</a>
<a href="#" id="reset-password-cancel-link" class="btn-operations btn-default">
Cancel
</a>
</div>
</div>
</div>
<div id="reset-password-success-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
Password reset is successful.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="reset-password-success-link" class="btn-operations">
Ok
</a>
</div>
</div>
</div> </div>
{{/zone}} {{/zone}}

@ -31,7 +31,8 @@ function onRequest(context) {
var userModule = require("/app/modules/business-controllers/user.js")["userModule"]; var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
page["adminUser"] = deviceMgtProps["adminUser"]; page["currentUser"] = userModule.getCarbonUser().username;
page["adminUser"] = deviceMgtProps["adminUser"].split("@")[0];
if (userModule.isAuthorized("/permission/admin/device-mgt/users/manage")) { if (userModule.isAuthorized("/permission/admin/device-mgt/users/manage")) {
page.canManage = true; page.canManage = true;

@ -1,481 +1,193 @@
{{unit "cdmf.unit.lib.qrcode"}} {{!
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"}} {{#zone "content"}}
{{#if deviceFound}} {{#if deviceFound}}
{{#if isAuthorized}} {{#if isAuthorized}}
<h1 class="page-sub-title device-id device-select" <h1 class="page-sub-title device-id device-select" data-deviceid="{{device.deviceIdentifier}}"
data-deviceid="{{deviceView.deviceIdentifier}}" data-type="{{deviceView.deviceType}}" data-type="{{device.type}}">
data-ownership="{{deviceView.ownership}}"> Device {{device.name}}
Device {{deviceView.name}} {{#if device.viewModel.model}}
{{#if deviceView.model}}
<span class="lbl-device"> <span class="lbl-device">
( {{deviceView.vendor}} {{deviceView.model}} ) ( {{device.viewModel.vendor}} {{device.viewModel.model}} )
</span> </span>
{{/if}} {{/if}}
</h1> </h1>
<div class="row no-gutter add-padding-5x add-margin-top-5x" style="border: 1px solid #e4e4e4;"> <div class="row no-gutter add-padding-5x add-margin-top-5x" style="border: 1px solid #e4e4e4;">
<div class="media"> <div class="media">
<div class="media-left media-middle asset-image col-xs-2 col-sm-2 col-md-2 col-lg-2"> <div id="device_overview">
<div class="thumbnail icon"><i class="square-element text fw fw-mobile"></i></div> <div class="media-left media-middle asset-image col-xs-2 col-sm-2 col-md-2 col-lg-2">
</div> <div class="thumbnail icon">
<div class="media-body asset-desc add-padding-left-5x"> {{#defineZone "device-thumbnail"}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Device <i class="square-element text fw fw-mobile"></i>
Overview {{/defineZone}}
</div> </div>
{{#defineZone "device-detail-properties"}}
<table class="table table-responsive table-striped" id="members">
<tbody>
{{#if deviceView.deviceIdentifier}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Device ID</td>
<td style="padding:10px 15px;">{{deviceView.deviceIdentifier}}</td>
</tr>
{{/if}}
{{#if deviceView.name}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Name</td>
<td style="padding:10px 15px;">{{deviceView.name}}</td>
</tr>
{{/if}}
{{#if deviceView.vendor}}
{{#if deviceView.model}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Model</td>
<td style="padding:10px 15px;">{{deviceView.vendor}} {{deviceView.model}}</td>
</tr>
{{/if}}
{{/if}}
{{#if deviceView.status}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Status</td>
<td style="padding:10px 15px;">
{{#equal deviceView.status "ACTIVE"}}<span><i
class="fw fw-ok icon-success"></i>Active</span>{{/equal}}
{{#equal deviceView.status "INACTIVE"}}<span><i
class="fw fw-warning icon-warning"></i>Inactive</span>{{/equal}}
{{#equal deviceView.status "BLOCKED"}}<span><i
class="fw fw-remove icon-danger"></i>Blocked</span>{{/equal}}
{{#equal deviceView.status "REMOVED"}}<span><i
class="fw fw-delete icon-danger"></i>Removed</span>{{/equal}}
</td>
</tr>
{{/if}}
{{#if deviceView.owner}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Owner</td>
<td style="padding:10px 15px;">{{deviceView.owner}}</td>
</tr>
{{/if}}
{{#if deviceView.ownership}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Ownership</td>
<td style="padding:10px 15px;">{{deviceView.ownership}}</td>
</tr>
{{/if}}
{{#if deviceView.imei}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">IMEI</td>
<td style="padding:10px 15px;">{{deviceView.imei}}</td>
</tr>
{{/if}}
{{#if deviceView.udid}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">UDID</td>
<td style="padding:10px 15px;">{{deviceView.udid}}</td>
</tr>
{{/if}}
{{#if deviceView.osBuildDate}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Firmware Build
Date
</td>
<td style="padding:10px 15px;">{{deviceView.osBuildDate}}</td>
</tr>
{{/if}}
{{#if deviceView.phoneNumber}}
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Phone Number</td>
<td style="padding:10px 15px;">{{deviceView.phoneNumber}}</td>
</tr>
{{/if}}
{{#if deviceView.lastUpdatedTime}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Last Update</td>
<td style="padding:10px 15px;">{{deviceView.lastUpdatedTime}}</td>
</tr>
{{/if}}
</tbody>
</table>
{{/defineZone}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Operations
</div> </div>
<div class="add-margin-top-4x"> <div class="media-body asset-desc add-padding-left-5x">
{{unit "mdm.unit.device.operation-bar" deviceType=deviceView.deviceType ownership=deviceView.ownership}} <div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Device Overview - {{label}}</div>
{{unit "cdmf.unit.device.overview-section" device=device}}
{{#defineZone "operation-status"}}{{/defineZone}}
{{#defineZone "device-opetations"}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Operations
</div>
<div class="add-margin-top-4x" style="height: 90px;">
{{unit "cdmf.unit.device.operation-bar" device=device}}
</div>
{{/defineZone}}
</div> </div>
</div> </div>
</div> </div>
<div class="media tab-responsive">
<div class="media-left col-xs-1 col-sm-1 col-md-2 col-lg-2 hidden-xs"> {{#defineZone "device-detail-properties"}}
<ul class="list-group nav nav-pills nav-stacked" role="tablist"> <div class="media">
{{#if deviceView.isNotWindows}} <div class="media-left col-xs-12 col-sm-2 col-md-2 col-lg-2">
<li role="presentation" class="list-group-item active"> <ul class="list-group" role="tablist">
<a href="#device_details_tab" role="tab" data-toggle="tab" <li class="active"><a class="list-group-item"
aria-controls="device_details_tab"> href="#device_details"
<i class="icon fw fw-mobile"></i><span class="hidden-sm">Device Details</span> role="tab" data-toggle="tab"
</a> aria-controls="device_details">Device
Details</a>
</li> </li>
{{/if}} <li><a class="list-group-item" href="#policies"
{{#if deviceView.isNotWindows}} role="tab"
<li role="presentation" class="list-group-item"> data-toggle="tab" aria-controls="policies">Policies</a>
{{else}}
<li role="presentation" class="list-group-item active">
{{/if}}
<li role="presentation" class="list-group-item">
<a href="#policy_compliance_tab" role="tab" data-toggle="tab"
aria-controls="policy_compliance_tab">
<i class="icon fw fw-policy"></i><span class="hidden-sm">Policy Compliance</span>
</a>
</li>
{{#if deviceView.isNotWindows}}
<li role="presentation" class="list-group-item">
<a href="#device_location_tab" role="tab" data-toggle="tab"
data-lat="{{deviceView.location.latitude}}"
data-long="{{deviceView.location.longitude}}"
aria-controls="device_location_tab">
<i class="icon fw fw-map-location"></i><span
class="hidden-sm">Device Location</span>
</a>
</li> </li>
<li role="presentation" class="list-group-item"> <li><a class="list-group-item" href="#policy_compliance"
<a href="#installed_applications_tab" role="tab" data-toggle="tab" role="tab"
aria-controls="installed_applications_tab"> data-toggle="tab" aria-controls="policy_compliance">Policy
<i class="icon fw fw-application"></i><span class="hidden-sm">Installed Applications</span> Compliance</a>
</a>
</li> </li>
{{/if}} <li><a class="list-group-item" href="#device_location"
{{#if deviceView.isNotRemoved}} role="tab"
data-toggle="tab" aria-controls="device_location">Device
<li role="presentation" class="list-group-item"> Location</a>
<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> </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">
{{/if}} <div class="panel panel-default tab-pane active"
</ul> id="device_details" role="tabpanel"
</div> aria-labelledby="device_details">
{{#defineZone "device-detail-properties"}} {{unit "cdmf.unit.device.details" device=device}}
<div class="media-body add-padding-left-5x remove-padding-xs"> </div>
<div class="panel-group tab-content remove-padding" id="tabs" data-status="{{deviceView.isNotRemoved}}"role="tablist" <div class="panel panel-default tab-pane" id="policies" role="tabpanel"
aria-multiselectable="true"> aria-labelledby="policies">
<div class="arrow-left hidden-xs"></div> <div class="panel-heading">Policies</div>
<div class="panel-body">
{{#if deviceView.isNotWindows}} <div id="policy-spinner" class="wr-advance-operations-init hidden">
<div class="panel panel-default" role="tabpanel" id="device_details_tab"> <br>
<div class="panel-heading visible-xs collapsed" id="device_details"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<h4 class="panel-title"> <i class="fw fw-settings fw-spin fw-2x"></i>
<a role="button" data-toggle="collapse" data-parent="#tabs" &nbsp;&nbsp;&nbsp;
href="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> Loading Policies . . .
<i class="fw fw-mobile fw-2x"></i> <br>
Device Details <br>
<i class="caret-updown fw fw-down"></i>
</a>
</h4>
</div> </div>
<div class="panel-heading display-none-xs">Device Details</div> <div id="policy-list-container">
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" <div class="panel-body">
aria-labelledby="device_details"> No policies found
<div class="panel-body ">
<div class="device-detail-body">
<!-- device summary -->
{{#equal deviceView.deviceType "windows"}}
<div class="message message-info">
<h4 class="remove-margin"><i class="icon fw fw-info"></i>Not
available yet</h4>
</div>
{{/equal}}
{{#if deviceView.deviceInfoAvailable}}
{{#if deviceView.BatteryLevel}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">BATTERY</div>
<div>
<div class="tile-icon"><i
class="fw fw-battery"></i></div>
<div class="tile-stats">
{{deviceView.BatteryLevel.value}} %
</div>
</div>
</div>
</div>
</div>
{{/if}}
<!--{{#if deviceView.cpuUsage}}-->
<!--<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">-->
<!--<div class="col-md-12">-->
<!--<div class="wr-stats-board-tile">-->
<!--<div class="tile-name">CPU Usage</div>-->
<!--<div>-->
<!--<div class="tile-icon"><i class="fw fw-dashboard"></i></div>-->
<!--<div class="tile-stats">-->
<!--{{deviceView.cpuUsage.value}} %-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--{{/if}}-->
{{#if deviceView.ramUsage}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">RAM Usage</div>
<div>
<div class="tile-icon"><i
class="fw fw-hardware"></i></div>
<div class="tile-stats">
{{deviceView.ramUsage.value}} %
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{#if deviceView.internalMemory}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">Local Storage</div>
<div>
<div class="tile-icon"><i
class="fw fw-hdd"></i>
</div>
<div class="tile-stats">
{{deviceView.internalMemory.usage}} %
<span class="tile-stats-free">
TOTAL OF {{deviceView.internalMemory.total}} GB
</span>
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{#if deviceView.externalMemory}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<div class="col-md-12">
<div class="wr-stats-board-tile">
<div class="tile-name">External Storage</div>
<div>
<div class="tile-icon"><i
class="fw fw-usb-drive"></i></div>
<div class="tile-stats">
{{deviceView.externalMemory.usage}} %
<span class="tile-stats-free">
TOTAL OF {{deviceView.externalMemory.total}} GB
</span>
</div>
</div>
</div>
</div>
</div>
{{/if}}
{{else}}
<div class="message message-info">
<h4 class="remove-margin">
<i class="icon fw fw-info"></i>
Battery, RAM and Storage related information are not
available yet.
</h4>
</div>
{{/if}}
</div>
</div> </div>
<br class="c-both" />
</div> </div>
</div> </div>
{{/if}} <a class="padding-left"
href="{{@app.context}}/policy/add/{{device.type}}?deviceId={{device.deviceIdentifier}}">
<div class="panel panel-default visible-xs-block" role="tabpanel" <span class="fw-stack">
id="policy_compliance_tab"> <i class="fw fw-ring fw-stack-2x"></i>
<div class="panel-heading visible-xs collapsed" id="policy_compliance"> <i class="fw fw-policy fw-stack-1x"></i>
<h4 class="panel-title"> </span> Add device specific policy</a>
<a role="button" </div>
data-toggle="collapse" data-parent="#tabs" href="#collapseTwo"
aria-expanded="true" aria-controls="collapseTwo">
<i class="fw fw-policy fw-2x"></i>
Policy Compliance
<i class="caret-updown fw fw-down"></i>
</a>
</h4>
</div>
<div class="panel-heading display-none-xs">
Policy Compliance
<span> <div class="panel panel-default tab-pane" id="policy_compliance"
<a href="javascript:void(0);" id="refresh-policy"> role="tabpanel" aria-labelledby="policy_compliance">
<i class="fw fw-refresh"></i> <div class="panel-heading">Policy Compliance <span><a
</a> href="#" id="refresh-policy"><i
</span> class="fw fw-refresh"></i></a></span></div>
</div> <div class="panel-body">
<div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" <div id="policy-spinner"
aria-labelledby="policy_compliance"> class="wr-advance-operations-init hidden">
<div class="panel-body "> <br>
<span class="visible-xs add-padding-2x text-right"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="javascript:void(0);" id="refresh-policy"> <i class="fw fw-settings fw-spin fw-2x"></i>
<i class="fw fw-refresh"></i> &nbsp;&nbsp;&nbsp;
</a> Loading Policy Compliance . . .
</span> <br>
<div id="policy-spinner" <br>
class="wr-advance-operations-init add-padding-bottom-2x add-padding-bottom-4x hidden"> </div>
<i class="fw fw-settings fw-spin fw-2x"></i>Loading Policy <div id="policy-list-container">
Compliance... <div class="panel-body">
</div> Not available yet
<div id="policy-list-container">
</div> </div>
<br class="c-both" />
</div> </div>
</div> </div>
</div> </div>
<div class="panel panel-default visible-xs-block" role="tabpanel" <div class="panel panel-default tab-pane" id="device_location"
id="device_location_tab"> role="tabpanel" aria-labelledby="device_location">
<div class="panel-heading visible-xs collapsed" id="device_location"> <div class="panel-heading">Device Location</div>
<h4 class="panel-title"> <div class="panel-body">
<a role="button" data-toggle="collapse" data-parent="#tabs" <div id="device-location"
href="#collapseThree" aria-expanded="true" aria-controls="collapseThree"> data-lat="{{device.viewModel.location.latitude}}"
<i class="fw fw-map-location fw-2x"></i> data-long="{{device.viewModel.location.longitude}}"
Device Location style="height:450px" class="panel-body">
<i class="caret-updown fw fw-down"></i>
</a>
</h4>
</div>
<div class="panel-heading display-none-xs">Device Location</div>
<div id="collapseThree" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="device_location">
<div class="panel-body">
{{#if deviceView.location}}
<div id="device-location"
data-lat="{{deviceView.location.latitude}}"
data-long="{{deviceView.location.longitude}}">
</div>
{{else}}
<div id="map-error" class="message message-warning">
<h4 class="remove-margin">
<i class="icon fw fw-warning"></i>
Device location information is not available.
</h4>
</div>
<p class="add-padding-5x"></p>
<p class="add-padding-5x"></p>
<p class="add-padding-5x"></p>
{{/if}}
</div> </div>
</div> <div id="map-error" class="panel-body">
</div> Not available yet
<div class="panel panel-default visible-xs-block" role="tabpanel"
id="installed_applications_tab">
<div class="panel-heading visible-xs collapsed" id="installed_applications">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#tabs"
href="#collapseFour" aria-expanded="true" aria-controls="collapseFour">
<i class="fw fw-application fw-2x"></i>
Installed Applications
<i class="caret-updown fw fw-down"></i>
</a>
</h4>
</div>
<div class="panel-heading display-none-xs">
Installed Applications
<span>
<a href="javascript:void(0);" id="refresh-apps">
<i class="fw fw-refresh"></i>
</a>
</span>
</div>
<div id="collapseFour" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="installed_applications">
<div class="panel-body">
<span class="visible-xs add-padding-2x text-right">
<a href="javascript:void(0);" id="refresh-apps">
<i class="fw fw-refresh"></i>
</a>
</span>
<div id="apps-spinner" class="wr-advance-operations-init hidden">
<i class="fw fw-settings fw-spin fw-2x"></i> Loading Applications
List...
</div>
<div id="applications-list-container">
<div class="message message-info">
<h4>
<i class="icon fw fw-info"></i>
No applications found.
</h4>
<p>Please try refreshing in a while.</p>
</div>
</div>
</div> </div>
<br class="c-both" />
</div> </div>
</div> </div>
<div class="panel panel-default visible-xs-block" role="tabpanel" id="event_log_tab"> <div class="panel panel-default tab-pane" id="event_log"
<div class="panel-heading visible-xs collapsed" id="event_log"> role="tabpanel" aria-labelledby="event_log">
<h4 class="panel-title"> <div class="panel-heading">Operations Log <span><a href="#"
<a role="button" data-toggle="collapse" data-parent="#tabs" id="refresh-operations"><i
href="#collapseFive" aria-expanded="true" aria-controls="collapseFive"> class="fw fw-refresh"></i></a></span></div>
<i class="fw fw-text fw-2x"></i> <div class="panel-body">
Operations Log <div id="operations-spinner"
<i class="caret-updown fw fw-down"></i> class="wr-advance-operations-init hidden">
</a> <br>
</h4> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</div> <i class="fw fw-settings fw-spin fw-2x"></i>
<div class="panel-heading display-none-xs"> &nbsp;&nbsp;&nbsp;
Operations Log Loading Operations Log . . .
<br>
<span> <br>
<a href="javascript:void(0);" id="refresh-operations"> </div>
<i class="fw fw-refresh"></i> <div id="operations-log-container">
</a> <div class="panel-body">
</span> Not available yet
</div>
<div id="collapseFive" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="event_log">
<div class="panel-body">
<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> </div>
<table class="table table-striped table-hover table-bordered display data-table" <br class="c-both" />
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> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{{/defineZone}} </div>
</div>
{{/defineZone}}
</div> </div>
{{else}} {{else}}
<h1 class="page-sub-title"> <h1 class="page-sub-title">
@ -493,21 +205,17 @@
{{/if}} {{/if}}
{{/zone}} {{/zone}}
{{#zone "bottomJs"}} {{#zone "bottomJs"}}
{{#if isAuthorized}} {{js "js/device-view.js"}}
<!--suppress HtmlUnknownTarget --> <script id="policy-view" src="{{@unit.publicUri}}/templates/policy-compliance.hbs"
<script id="policy-view" src="{{@unit.publicUri}}/templates/policy-compliance.hbs" data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
data-device-id="{{deviceView.deviceIdentifier}}" data-device-type="{{deviceView.deviceType}}" type="text/x-handlebars-template"></script>
type="text/x-handlebars-template"></script> <script id="policy-list" src="{{@unit.publicUri}}/templates/policy-list.hbs"
<!--suppress HtmlUnknownTarget --> data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
<script id="applications-list" src="{{@unit.publicUri}}/templates/applications-list.hbs" type="text/x-handlebars-template"></script>
data-device-id="{{deviceView.deviceIdentifier}}" data-device-type="{{deviceView.deviceType}}" <script id="applications-list" src="{{@unit.publicUri}}/templates/applications-list.hbs"
type="text/x-handlebars-template"></script> data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
<!--suppress HtmlUnknownTarget --> type="text/x-handlebars-template"></script>
<script id="operations-log" src="{{@unit.publicUri}}/templates/operations-log.hbs" <script id="operations-log" src="{{@unit.publicUri}}/templates/operations-log.hbs"
data-device-id="{{deviceView.deviceIdentifier}}" data-device-type="{{deviceView.deviceType}}" data-device-id="{{device.deviceIdentifier}}" data-device-type="{{device.type}}"
type="text/x-handlebars-template"></script> type="text/x-handlebars-template"></script>
{{js "js/device-detail.js"}}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
{{js "js/load-map.js"}}
{{/if}}
{{/zone}} {{/zone}}

@ -1,118 +1,210 @@
/* /*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* *
* WSO2 Inc. licenses this file to you under the Apache License, * WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except * Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. * in compliance with the License.
* You may obtain a copy of the License at * 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, * Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an * software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* KIND, either express or implied. See the License for the * either express or implied. See the License for the
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
function onRequest(context) { function onRequest(context) {
var log = new Log("detail.js"); var log = new Log("cdmf.unit.device.view/view.js");
var deviceType = context.uriParams.deviceType; var deviceType = context["uriParams"]["deviceType"];
var deviceId = request.getParameter("id"); var deviceId = request.getParameter("id");
var deviceViewData = {};
if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) { if (deviceType && deviceId) {
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"]; var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var device = deviceModule.viewDevice(deviceType, deviceId)["content"]; var response = deviceModule.viewDevice(deviceType, deviceId);
if (response["status"] == "success") {
deviceViewData["deviceFound"] = true;
deviceViewData["isAuthorized"] = true;
var filteredDeviceData = response["content"];
if (device) { // creating deviceView information model from filtered device data
var viewModel = {}; var viewModel = {};
var deviceInfo = (device.properties) ? device.properties.DEVICE_INFO : null; if (filteredDeviceData["type"]) {
if (deviceInfo != undefined && String(deviceInfo.toString()).length > 0) { viewModel["deviceType"] = filteredDeviceData["type"];
deviceInfo = parse(stringify(deviceInfo)); viewModel.isNotWindows = true;
if (device.type == "ios") { if (viewModel["deviceType"] == "windows") {
deviceInfo = parse(deviceInfo); viewModel.isNotWindows = false;
viewModel.imei = device.properties.IMEI; }
viewModel.phoneNumber = deviceInfo.PhoneNumber; }
viewModel.udid = deviceInfo.UDID; if (filteredDeviceData["deviceIdentifier"]) {
viewModel.BatteryLevel = Math.round(deviceInfo.BatteryLevel * 100); viewModel["deviceIdentifier"] = filteredDeviceData["deviceIdentifier"];
viewModel.DeviceCapacity = Math.round(deviceInfo.DeviceCapacity * 100) / 100; }
viewModel.AvailableDeviceCapacity = Math.round(deviceInfo.AvailableDeviceCapacity * 100) / 100; if (filteredDeviceData["name"]) {
viewModel.DeviceCapacityUsed = Math.round((viewModel.DeviceCapacity viewModel["name"] = filteredDeviceData["name"];
- viewModel.AvailableDeviceCapacity) * 100) / 100; }
viewModel.DeviceCapacityPercentage = Math.round(viewModel.AvailableDeviceCapacity if (filteredDeviceData["enrolmentInfo"]) {
/ viewModel.DeviceCapacity * 10000) / 100; if (filteredDeviceData["enrolmentInfo"]["status"]) {
viewModel.location = { viewModel["status"] = filteredDeviceData["enrolmentInfo"]["status"];
latitude: device.properties.LATITUDE, viewModel.isActive = false ;
longitude: device.properties.LONGITUDE viewModel.isNotRemoved = true;
}; if (filteredDeviceData["enrolmentInfo"]["status"]== "ACTIVE") {
} else if (device.type == "android") { viewModel.isActive = true ;
viewModel.imei = device.properties.IMEI; }
viewModel.model = device.properties.DEVICE_MODEL; if (filteredDeviceData["enrolmentInfo"]["status"]== "REMOVED") {
viewModel.vendor = device.properties.VENDOR; viewModel.isNotRemoved = false ;
viewModel.internal_memory = {}; }
viewModel.external_memory = {}; }
viewModel.location = { if (filteredDeviceData["enrolmentInfo"]["owner"]) {
latitude: device.properties.LATITUDE, viewModel["owner"] = filteredDeviceData["enrolmentInfo"]["owner"];
longitude: device.properties.LONGITUDE }
}; if (filteredDeviceData["enrolmentInfo"]["ownership"]) {
var info = {}; viewModel["ownership"] = filteredDeviceData["enrolmentInfo"]["ownership"];
var infoList = parse(deviceInfo); }
if (infoList != null && infoList != undefined) { }
for (var j = 0; j < infoList.length; j++) { if (filteredDeviceData["initialDeviceInfo"]) {
info[infoList[j].name] = infoList[j].value; viewModel["deviceInfoAvailable"] = true;
if (filteredDeviceData["initialDeviceInfo"]["IMEI"]) {
viewModel["imei"] = filteredDeviceData["initialDeviceInfo"]["IMEI"];
}
if (!filteredDeviceData["latestDeviceInfo"]) {
if (filteredDeviceData["initialDeviceInfo"]["OS_BUILD_DATE"]) {
if (filteredDeviceData["initialDeviceInfo"]["OS_BUILD_DATE"] != "0") {
viewModel["osBuildDate"] = new Date(filteredDeviceData["initialDeviceInfo"]["OS_BUILD_DATE"] * 1000);
}
}
if (filteredDeviceData["initialDeviceInfo"]["LATITUDE"] && filteredDeviceData["initialDeviceInfo"]["LONGITUDE"]) {
viewModel["location"] = {};
viewModel["location"]["latitude"] = filteredDeviceData["initialDeviceInfo"]["LATITUDE"];
viewModel["location"]["longitude"] = filteredDeviceData["initialDeviceInfo"]["LONGITUDE"];
}
if (filteredDeviceData["initialDeviceInfo"]["VENDOR"] && filteredDeviceData["initialDeviceInfo"]["DEVICE_MODEL"]) {
viewModel["vendor"] = filteredDeviceData["initialDeviceInfo"]["VENDOR"];
viewModel["model"] = filteredDeviceData["initialDeviceInfo"]["DEVICE_MODEL"];
}
if (filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]) {
if (deviceType == "android") {
viewModel["BatteryLevel"] = {};
viewModel["BatteryLevel"]["value"] = filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["BATTERY_LEVEL"];
viewModel["internalMemory"] = {};
viewModel["internalMemory"]["total"] = Math.
round(filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["INTERNAL_TOTAL_MEMORY"] * 100) / 100;
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;
} else {
viewModel["internalMemory"]["usage"] = 0;
}
viewModel["externalMemory"] = {};
viewModel["externalMemory"]["total"] = Math.
round(filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["EXTERNAL_TOTAL_MEMORY"] * 100) / 100;
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;
} else {
viewModel["externalMemory"]["usage"] = 0;
}
} else if (deviceType == "ios") {
viewModel["BatteryLevel"] = {};
viewModel["BatteryLevel"]["value"] = filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["BatteryLevel"];
viewModel["internalMemory"] = {};
viewModel["internalMemory"]["total"] = Math.
round(filteredDeviceData["initialDeviceInfo"]["DEVICE_INFO"]["DeviceCapacity"] * 100) / 100;
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;
} else {
viewModel["internalMemory"]["usage"] = 0;
}
} }
} }
deviceInfo = info;
viewModel.BatteryLevel = deviceInfo.BATTERY_LEVEL;
viewModel.internal_memory.FreeCapacity = Math.round(deviceInfo.INTERNAL_AVAILABLE_MEMORY * 100)/100;
viewModel.internal_memory.DeviceCapacityPercentage = Math.round(deviceInfo.INTERNAL_AVAILABLE_MEMORY
/ deviceInfo.INTERNAL_TOTAL_MEMORY * 10000) / 100;
viewModel.external_memory.FreeCapacity = Math.round(deviceInfo.EXTERNAL_AVAILABLE_MEMORY * 100) / 100;
viewModel.external_memory.DeviceCapacityPercentage = Math.round(deviceInfo.EXTERNAL_AVAILABLE_MEMORY
/ deviceInfo.EXTERNAL_TOTAL_MEMORY * 10000) / 100;
} else if (device.type == "windows") {
viewModel.imei = device.properties.IMEI;
viewModel.model = device.properties.DEVICE_MODEL;
viewModel.vendor = device.properties.VENDOR;
viewModel.internal_memory = {};
viewModel.external_memory = {};
viewModel.location = {
latitude: device.properties.LATITUDE,
longitude: device.properties.LONGITUDE
};
/*var info = {};
if (deviceInfo != null && deviceInfo != undefined){
var infoList = parse(deviceInfo);
if (infoList != null && infoList != undefined) {
for (var j = 0; j < infoList.length; j++) {
info[infoList[j].name] = infoList[j].value;
}
}
deviceInfo = info;
viewModel.BatteryLevel = deviceInfo.BATTERY_LEVEL;
viewModel.internal_memory.FreeCapacity = Math.round((deviceInfo.INTERNAL_TOTAL_MEMORY -
deviceInfo.INTERNAL_AVAILABLE_MEMORY) * 100) / 100;
viewModel.internal_memory.DeviceCapacityPercentage = Math.round(deviceInfo.INTERNAL_AVAILABLE_MEMORY
/ deviceInfo.INTERNAL_TOTAL_MEMORY * 10000) / 100;
viewModel.external_memory.FreeCapacity = Math.round((deviceInfo.EXTERNAL_TOTAL_MEMORY -
deviceInfo.EXTERNAL_AVAILABLE_MEMORY) * 100) / 100;
viewModel.external_memory.DeviceCapacityPercentage = Math.round(deviceInfo.EXTERNAL_AVAILABLE_MEMORY
/ deviceInfo.EXTERNAL_TOTAL_MEMORY * 10000) / 100;
}*/
}else if (device.type == "TemperatureController") {
viewModel.system = device.properties.IMEI;
viewModel.machine = device.properties.DEVICE_MODEL;
viewModel.vendor = device.properties.VENDOR;
viewModel.internal_memory = {};
viewModel.external_memory = {};
} }
device.viewModel = viewModel;
} }
} if (filteredDeviceData["latestDeviceInfo"]) {
viewModel["deviceInfoAvailable"] = true;
if (filteredDeviceData["latestDeviceInfo"]["osBuildDate"]) {
if (filteredDeviceData["latestDeviceInfo"]["osBuildDate"] != "0") {
viewModel["osBuildDate"] = new Date(filteredDeviceData["latestDeviceInfo"]["osBuildDate"] * 1000);
}
}
if (filteredDeviceData["latestDeviceInfo"]["location"]["latitude"] &&
filteredDeviceData["latestDeviceInfo"]["location"]["longitude"]) {
viewModel["location"] = {};
viewModel["location"]["latitude"] = filteredDeviceData["latestDeviceInfo"]["location"]["latitude"];
viewModel["location"]["longitude"] = filteredDeviceData["latestDeviceInfo"]["location"]["longitude"];
}
if (filteredDeviceData["latestDeviceInfo"]["vendor"] && filteredDeviceData["latestDeviceInfo"]["deviceModel"]) {
viewModel["vendor"] = filteredDeviceData["latestDeviceInfo"]["vendor"];
viewModel["model"] = filteredDeviceData["latestDeviceInfo"]["deviceModel"];
}
if (filteredDeviceData["latestDeviceInfo"]["updatedTime"]) {
viewModel["lastUpdatedTime"] = filteredDeviceData["latestDeviceInfo"]["updatedTime"].
substr(0, filteredDeviceData["latestDeviceInfo"]["updatedTime"].indexOf("+"));
}
viewModel["BatteryLevel"] = {};
viewModel["BatteryLevel"]["value"] = filteredDeviceData["latestDeviceInfo"]["batteryLevel"];
viewModel["cpuUsage"] = {};
viewModel["cpuUsage"]["value"] = filteredDeviceData["latestDeviceInfo"]["cpuUsage"];
var utility = require("/app/modules/utility.js").utility; viewModel["ramUsage"] = {};
var configs = utility.getDeviceTypeConfig(deviceType); if (filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] != 0) {
return {"device": device, "label" : configs["deviceType"]["label"]}; viewModel["ramUsage"]["value"] = Math.
round((filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] -
filteredDeviceData["latestDeviceInfo"]["availableRAMMemory"])
/ filteredDeviceData["latestDeviceInfo"]["totalRAMMemory"] * 10000) / 100;
} else {
viewModel["ramUsage"]["value"] = 0;
}
viewModel["internalMemory"] = {};
viewModel["internalMemory"]["total"] = Math.
round(filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] * 100) / 100;
if (filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] != 0) {
viewModel["internalMemory"]["usage"] = Math.
round((filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] -
filteredDeviceData["latestDeviceInfo"]["internalAvailableMemory"])
/ filteredDeviceData["latestDeviceInfo"]["internalTotalMemory"] * 10000) / 100;
} else {
viewModel["internalMemory"]["usage"] = 0;
}
viewModel["externalMemory"] = {};
viewModel["externalMemory"]["total"] = Math.
round(filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] * 100) / 100;
if (filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] != 0) {
viewModel["externalMemory"]["usage"] = Math.
round((filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] -
filteredDeviceData["latestDeviceInfo"]["externalAvailableMemory"])
/ filteredDeviceData["latestDeviceInfo"]["externalTotalMemory"] * 10000) / 100;
} else {
viewModel["externalMemory"]["usage"] = 0;
}
}
if (!filteredDeviceData["initialDeviceInfo"] && !filteredDeviceData["latestDeviceInfo"]) {
viewModel["deviceInfoAvailable"] = false;
}
deviceViewData["deviceView"] = viewModel;
} else if (response["status"] == "unauthorized") {
deviceViewData["deviceFound"] = true;
deviceViewData["isAuthorized"] = false;
} else if (response["status"] == "notFound") {
deviceViewData["deviceFound"] = false;
}
} else {
deviceViewData["deviceFound"] = false;
} }
return deviceViewData;
} }

@ -0,0 +1,51 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
{{#zone "content"}}
<div id="basic-modal-view" class="hidden modal modal-content">
<div class="modal-header">
<h3 class="pull-left modal-title">
<span class="fw-stack error-msg-icon hidden">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i>
</span>
<span class="fw-stack warning-msg-icon hidden">
<i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-warning fw-stack-1x"></i>
</span>
<span id="modal-title-text"></span>
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<h4 id="modal-content-text">
</h4>
</div>
<div id="modal-footer-content" class="modal-footer">
</div>
</div>
{{/zone}}
{{#zone "topJs"}}
{{js "js/modal.js"}}
{{/zone}}

@ -0,0 +1,72 @@
/**
* 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.
*/
var modalDialog = (function () {
var publicMethoads = {};
publicMethoads.header = function (headerText) {
$("#modal-title-text").html(headerText);
};
publicMethoads.content = function (contentText) {
$("#modal-content-text").html(contentText);
};
publicMethoads.footer = function (footerContent) {
$("#modal-footer-content").html(footerContent);
};
publicMethoads.footerButtons = function (buttonList) {
var footerContent = "";
for (var btn in buttonList) {
footerContent = footerContent + '<div class="buttons"><a href="#" id="' + btn.id +
'" class="btn-operations">' + btn.text + '</a></div>';
}
$("#modal-footer-content").html(footerContent);
};
publicMethoads.show = function () {
$(".error-msg-icon").addClass("hidden");
$(".warning-msg-icon").addClass("hidden");
$("#basic-modal-view").removeClass('hidden');
$("#basic-modal-view").modal('show');
};
publicMethoads.showAsError = function () {
$(".error-msg-icon").removeClass("hidden");
$("#basic-modal-view").removeClass('hidden');
$("#basic-modal-view").modal('show');
};
publicMethoads.showAsAWarning = function () {
$(".warning-msg-icon").removeClass("hidden");
$("#basic-modal-view").removeClass('hidden');
$("#basic-modal-view").modal('show');
};
publicMethoads.hide = function () {
$("#basic-modal-view").addClass('hidden');
$("#basic-modal-view").modal('hide');
$("#modal-title-text").html("");
$("#modal-content-text").html("");
$("#modal-footer-content").html("");
$('body').removeClass('modal-open').css('padding-right', '0px');
$('.modal-backdrop').remove();
};
return publicMethoads;
}(modalDialog));

@ -380,8 +380,11 @@ public class MonitoringManagerImpl implements MonitoringManager {
List<String> deviceTypes = new ArrayList<>(); List<String> deviceTypes = new ArrayList<>();
try { try {
//when shutdown, it sets DeviceManagementService to null, therefore need to have a null check
if (PolicyManagementDataHolder.getInstance().getDeviceManagementService() != null) {
deviceTypes = deviceTypes =
PolicyManagementDataHolder.getInstance().getDeviceManagementService().getAvailableDeviceTypes(); PolicyManagementDataHolder.getInstance().getDeviceManagementService().getAvailableDeviceTypes();
}
} catch (DeviceManagementException e) { } catch (DeviceManagementException e) {
throw new PolicyComplianceException("Error occurred while getting the device types.", e); throw new PolicyComplianceException("Error occurred while getting the device types.", e);
} }

@ -23,6 +23,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.ntask.core.Task; import org.wso2.carbon.ntask.core.Task;
import org.wso2.carbon.policy.mgt.common.monitor.PolicyComplianceException; import org.wso2.carbon.policy.mgt.common.monitor.PolicyComplianceException;
@ -59,8 +61,14 @@ public class MonitoringTask implements Task {
MonitoringManager monitoringManager = PolicyManagementDataHolder.getInstance().getMonitoringManager(); MonitoringManager monitoringManager = PolicyManagementDataHolder.getInstance().getMonitoringManager();
List<String> deviceTypes = new ArrayList<>(); List<String> deviceTypes = new ArrayList<>();
List<String> configDeviceTypes = new ArrayList<>();
try { try {
deviceTypes = monitoringManager.getDeviceTypes(); deviceTypes = monitoringManager.getDeviceTypes();
for (String deviceType : deviceTypes) {
if (isPlatformExist(deviceType)) {
configDeviceTypes.add(deviceType);
}
}
} catch (PolicyComplianceException e) { } catch (PolicyComplianceException e) {
log.error("Error occurred while getting the device types."); log.error("Error occurred while getting the device types.");
} }
@ -68,7 +76,7 @@ public class MonitoringTask implements Task {
try { try {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementProviderService deviceManagementProviderService =
PolicyManagementDataHolder.getInstance().getDeviceManagementService(); PolicyManagementDataHolder.getInstance().getDeviceManagementService();
for (String deviceType : deviceTypes) { for (String deviceType : configDeviceTypes) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Running task for device type : " + deviceType); log.debug("Running task for device type : " + deviceType);
} }
@ -82,6 +90,7 @@ public class MonitoringTask implements Task {
deviceType); deviceType);
} }
for (Device device : devices) { for (Device device : devices) {
EnrolmentInfo.Status status = device.getEnrolmentInfo().getStatus(); EnrolmentInfo.Status status = device.getEnrolmentInfo().getStatus();
if (status.equals(EnrolmentInfo.Status.BLOCKED) || if (status.equals(EnrolmentInfo.Status.BLOCKED) ||
status.equals(EnrolmentInfo.Status.REMOVED) || status.equals(EnrolmentInfo.Status.REMOVED) ||
@ -116,4 +125,18 @@ public class MonitoringTask implements Task {
} }
} }
/**
* Check whether Device platform (ex: android) is exist in the cdm-config.xml file before adding a
* Monitoring operation to a specific device type.
*
* @param deviceType available device types.
* @return return platform is exist(true) or not (false).
*/
private boolean isPlatformExist(String deviceType) {
PolicyConfiguration policyConfiguration =
DeviceConfigurationManager.getInstance().getDeviceManagementConfig().getPolicyConfiguration();
return (policyConfiguration.getPlatforms().contains(deviceType));
}
} }

@ -42,6 +42,11 @@
<MaxRetries>5</MaxRetries> <MaxRetries>5</MaxRetries>
<MinRetriesToMarkUnreachable>8</MinRetriesToMarkUnreachable> <MinRetriesToMarkUnreachable>8</MinRetriesToMarkUnreachable>
<MinRetriesToMarkInactive>20</MinRetriesToMarkInactive> <MinRetriesToMarkInactive>20</MinRetriesToMarkInactive>
<Platforms>
<Platform>android</Platform>
<Platform>ios</Platform>
<Platform>windows</Platform>
</Platforms>
</PolicyConfiguration> </PolicyConfiguration>
<TaskConfiguration> <TaskConfiguration>
<Enable>true</Enable> <Enable>true</Enable>

Loading…
Cancel
Save