Merge pull request #667 from wso2/cloud-3.1.0

Cloud 3.1.0 changes
revert-70aa11f8
Amal Gunatilake 8 years ago committed by GitHub
commit 56b5f82ef8

@ -423,6 +423,83 @@ public interface DeviceManagementService {
@HeaderParam("If-Modified-Since") @HeaderParam("If-Modified-Since")
String ifModifiedSince); String ifModifiedSince);
@GET
@Path("/{type}/{id}/location")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Location Details of a Device",
notes = "Get the location details of a device by specifying the device type and device identifier.",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the location details 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 was last modified.\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.\n"),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found. \n Location data for the specified device was not found.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while retrieving the device details.",
response = ErrorResponse.class)
})
Response getDeviceLocation(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(max = 45)
String type,
@ApiParam(
name = "id",
value = "The device identifier of the device you want ot get details.",
required = true)
@PathParam("id")
@Size(max = 45)
String id,
@ApiParam(
name = "If-Modified-Since",
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)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
//device rename request would looks like follows //device rename request would looks like follows
//POST devices/type/virtual_firealarm/id/us06ww93auzp/rename //POST devices/type/virtual_firealarm/id/us06ww93auzp/rename
@POST @POST
@ -575,7 +652,7 @@ public interface DeviceManagementService {
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Getting Feature Details of a Device", value = "Getting Feature Details of a Device",
notes = "WSO2 EMM features enable you to carry out many operations based on the device platform. " + notes = "WSO2 IoTS features enable you to carry out many operations based on the device platform. " +
"Using this REST API you can get the features that can be carried out on a preferred device type," + "Using this REST API you can get the features that can be carried out on a preferred device type," +
" such as iOS, Android or Windows.", " such as iOS, Android or Windows.",
tags = "Device Management", tags = "Device Management",
@ -644,7 +721,7 @@ public interface DeviceManagementService {
@ApiParam( @ApiParam(
name = "id", name = "id",
value = "The device identifier of the device.\n" + value = "The device identifier of the device.\n" +
"INFO: Make sure to add the ID of a device that is already registered with WSO2 EMM.", "INFO: Make sure to add the ID of a device that is already registered with WSO2 IoTS.",
required = true) required = true)
@PathParam("id") @PathParam("id")
@Size(max = 45) @Size(max = 45)
@ -911,7 +988,7 @@ public interface DeviceManagementService {
@ApiParam( @ApiParam(
name = "id", name = "id",
value = "The device identifier of the device you wish to get details.\n" + value = "The device identifier of the device you wish to get details.\n" +
"INFO: Make sure to add the ID of a device that is already registered with WSO2 EMM.", "INFO: Make sure to add the ID of a device that is already registered with WSO2 IoTS.",
required = true) required = true)
@PathParam("id") @PathParam("id")
@Size(max = 45) @Size(max = 45)
@ -952,8 +1029,8 @@ public interface DeviceManagementService {
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Get the details of the policy that is enforced on a device.", value = "Get the details of the policy that is enforced on a device.",
notes = "A policy is enforced on all the devices that register with WSO2 EMM." + notes = "A policy is enforced on all the devices that register with WSO2 IoTS." +
"WSO2 EMM filters the policies based on the device platform (device type)," + "WSO2 IoTS filters the policies based on the device platform (device type)," +
"the device ownership type, the user role or name and finally, the policy that matches these filters will be enforced on the device.", "the device ownership type, the user role or name and finally, the policy that matches these filters will be enforced on the device.",
tags = "Device Management", tags = "Device Management",
extensions = { extensions = {
@ -1041,7 +1118,7 @@ public interface DeviceManagementService {
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Getting Policy Compliance Details of a Device", value = "Getting Policy Compliance Details of a Device",
notes = "A policy is enforced on the devices that register with WSO2 EMM. " + notes = "A policy is enforced on the devices that register with WSO2 IoTS. " +
"The server checks if the settings in the device comply with the policy that is enforced on the device using this REST API.", "The server checks if the settings in the device comply with the policy that is enforced on the device using this REST API.",
tags = "Device Management", tags = "Device Management",
extensions = { extensions = {

@ -18,6 +18,7 @@
*/ */
package org.wso2.carbon.device.mgt.jaxrs.service.impl; package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -34,6 +35,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
@ -41,6 +43,8 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
import org.wso2.carbon.device.mgt.common.search.SearchContext; import org.wso2.carbon.device.mgt.common.search.SearchContext;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService;
import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException; import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
@ -99,8 +103,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(role)) { if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(role)) {
return Response.status(Response.Status.BAD_REQUEST).entity( return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Request contains both name and role " + new ErrorResponse.ErrorResponseBuilder().setMessage("Request contains both name and role " +
"parameters. Only one is allowed " + "parameters. Only one is allowed " +
"at once.").build()).build(); "at once.").build()).build();
} }
// RequestValidationUtil.validateSelectionCriteria(type, user, roleName, ownership, status); // RequestValidationUtil.validateSelectionCriteria(type, user, roleName, ownership, status);
RequestValidationUtil.validatePaginationParameters(offset, limit); RequestValidationUtil.validatePaginationParameters(offset, limit);
@ -110,7 +114,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
if (deviceAccessAuthorizationService == null) { if (deviceAccessAuthorizationService == null) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Device access authorization service is " + new ErrorResponse.ErrorResponseBuilder().setMessage("Device access authorization service is " +
"failed").build()).build(); "failed").build()).build();
} }
PaginationRequest request = new PaginationRequest(offset, limit); PaginationRequest request = new PaginationRequest(offset, limit);
PaginationResult result; PaginationResult result;
@ -133,7 +137,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
RequestValidationUtil.validateStatus(status); RequestValidationUtil.validateStatus(status);
request.setStatus(status); request.setStatus(status);
} }
if (groupId != 0 ) { if (groupId != 0) {
request.setGroupId(groupId); request.setGroupId(groupId);
} }
if (role != null && !role.isEmpty()) { if (role != null && !role.isEmpty()) {
@ -155,7 +159,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
request.setOwner(user); request.setOwner(user);
} else { } else {
String msg = "User '" + authorizedUser + "' is not authorized to retrieve devices of '" + user String msg = "User '" + authorizedUser + "' is not authorized to retrieve devices of '" + user
+ "' user"; + "' user";
log.error(msg); log.error(msg);
return Response.status(Response.Status.UNAUTHORIZED).entity( return Response.status(Response.Status.UNAUTHORIZED).entity(
new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build();
@ -330,12 +334,12 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
} catch (ParseException e) { } catch (ParseException e) {
return Response.status(Response.Status.BAD_REQUEST).entity( return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " +
"string is provided in 'If-Modified-Since' header").build()).build(); "string is provided in 'If-Modified-Since' header").build()).build();
} }
device = dms.getDevice(new DeviceIdentifier(id, type), sinceDate); device = dms.getDevice(new DeviceIdentifier(id, type), sinceDate);
if (device == null) { if (device == null) {
return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " +
"after the timestamp provided in 'If-Modified-Since' header").build(); "after the timestamp provided in 'If-Modified-Since' header").build();
} }
} else { } else {
device = dms.getDevice(new DeviceIdentifier(id, type)); device = dms.getDevice(new DeviceIdentifier(id, type));
@ -359,6 +363,32 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
return Response.status(Response.Status.OK).entity(device).build(); return Response.status(Response.Status.OK).entity(device).build();
} }
@GET
@Path("/{type}/{id}/location")
@Override
public Response getDeviceLocation(
@PathParam("type") @Size(max = 45) String type,
@PathParam("id") @Size(max = 45) String id,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
DeviceInformationManager informationManager;
DeviceLocation deviceLocation;
try {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(id);
deviceIdentifier.setType(type);
informationManager = DeviceMgtAPIUtils.getDeviceInformationManagerService();
deviceLocation = informationManager.getDeviceLocation(deviceIdentifier);
} catch (DeviceDetailsMgtException e) {
String msg = "Error occurred while getting the device location.";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity(deviceLocation).build();
}
@GET @GET
@Path("/{type}/{id}/features") @Path("/{type}/{id}/features")
@Override @Override

@ -30,37 +30,20 @@ import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.FilteringUtil;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.device.mgt.jaxrs.util.SetReferenceTransformer; import org.wso2.carbon.device.mgt.jaxrs.util.SetReferenceTransformer;
import org.wso2.carbon.user.api.AuthorizationManager; import org.wso2.carbon.user.api.*;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.common.AbstractUserStoreManager; import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
import org.wso2.carbon.user.mgt.UserRealmProxy; import org.wso2.carbon.user.mgt.UserRealmProxy;
import org.wso2.carbon.user.mgt.common.UIPermissionNode; import org.wso2.carbon.user.mgt.common.UIPermissionNode;
import org.wso2.carbon.user.mgt.common.UserAdminException; import org.wso2.carbon.user.mgt.common.UserAdminException;
import javax.ws.rs.Consumes; import javax.ws.rs.*;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.wso2.carbon.device.mgt.jaxrs.util.Constants.PRIMARY_USER_STORE; import static org.wso2.carbon.device.mgt.jaxrs.util.Constants.PRIMARY_USER_STORE;
@ -105,6 +88,48 @@ public class RoleManagementServiceImpl implements RoleManagementService {
} }
} }
@GET
@Path("/filter/{prefix}")
@Override
public Response getFilteredRoles(
@PathParam("prefix") String prefix,
@QueryParam("filter") String filter,
@QueryParam("user-store") String userStore,
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@QueryParam("offset") int offset, @QueryParam("limit") int limit) {
RequestValidationUtil.validatePaginationParameters(offset, limit);
List<String> finalRoleList;
RoleList targetRoles = new RoleList();
//if user store is null set it to primary
if (userStore == null || "".equals(userStore)) {
userStore = PRIMARY_USER_STORE;
}
try {
//Get the total role count that matches the given filter
List<String> filteredRoles = getRolesFromUserStore(filter, userStore);
finalRoleList = new ArrayList<String>();
filteredRoles = FilteringUtil.getFilteredList(getRolesFromUserStore(filter, userStore), offset, limit);
for (String rolename : filteredRoles){
if (rolename.startsWith(prefix)){
finalRoleList.add(rolename);
}
}
targetRoles.setCount(finalRoleList.size());
targetRoles.setList(finalRoleList);
return Response.ok().entity(targetRoles).build();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving roles from the underlying user stores";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@GET @GET
@Path("/{roleName}/permissions") @Path("/{roleName}/permissions")
@Override @Override
@ -208,7 +233,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
if (!userStoreManager.isExistingRole(roleName)) { if (!userStoreManager.isExistingRole(roleName)) {
return Response.status(404).entity( return Response.status(404).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" +
roleName + "'").build()).build(); roleName + "'").build()).build();
} }
roleInfo.setRoleName(roleName); roleInfo.setRoleName(roleName);
roleInfo.setUsers(userStoreManager.getUserListOfRole(roleName)); roleInfo.setUsers(userStoreManager.getUserListOfRole(roleName));
@ -275,7 +300,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
//TODO fix what's returned in the entity //TODO fix what's returned in the entity
return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleInfo.getRoleName(), "UTF-8"))). return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleInfo.getRoleName(), "UTF-8"))).
entity("Role '" + roleInfo.getRoleName() + "' has " + "successfully been" entity("Role '" + roleInfo.getRoleName() + "' has " + "successfully been"
+ " added").build(); + " added").build();
} catch (UserStoreException e) { } catch (UserStoreException e) {
String msg = "Error occurred while adding role '" + roleInfo.getRoleName() + "'"; String msg = "Error occurred while adding role '" + roleInfo.getRoleName() + "'";
log.error(msg, e); log.error(msg, e);
@ -335,7 +360,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
//TODO fix what's returned in the entity //TODO fix what's returned in the entity
return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleName, "UTF-8"))). return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleName, "UTF-8"))).
entity("Role '" + roleName + "' has " + "successfully been" entity("Role '" + roleName + "' has " + "successfully been"
+ " added").build(); + " added").build();
} catch (UserAdminException e) { } catch (UserAdminException e) {
String msg = "Error occurred while retrieving the permissions of role '" + roleName + "'"; String msg = "Error occurred while retrieving the permissions of role '" + roleName + "'";
log.error(msg, e); log.error(msg, e);
@ -376,7 +401,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
if (!userStoreManager.isExistingRole(roleName)) { if (!userStoreManager.isExistingRole(roleName)) {
return Response.status(404).entity( return Response.status(404).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" +
roleName + "'").build()).build(); roleName + "'").build()).build();
} }
final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager(); final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager();
@ -392,7 +417,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
if (roleInfo.getUsers() != null) { if (roleInfo.getUsers() != null) {
SetReferenceTransformer<String> transformer = new SetReferenceTransformer<>(); SetReferenceTransformer<String> transformer = new SetReferenceTransformer<>();
transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(newRoleName)), transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(newRoleName)),
Arrays.asList(roleInfo.getUsers())); Arrays.asList(roleInfo.getUsers()));
final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer
.getObjectsToAdd().size()]); .getObjectsToAdd().size()]);
final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer
@ -404,7 +429,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
// Get all role permissions // Get all role permissions
final UIPermissionNode rolePermissions = this.getAllRolePermissions(roleName, userRealm); final UIPermissionNode rolePermissions = this.getAllRolePermissions(roleName, userRealm);
List<String> permissions = new ArrayList<String>(); List<String> permissions = new ArrayList<String>();
final UIPermissionNode emmRolePermissions = (UIPermissionNode)this.getRolePermissions(roleName); final UIPermissionNode emmRolePermissions = (UIPermissionNode) this.getRolePermissions(roleName);
List<String> emmConsolePermissions = new ArrayList<String>(); List<String> emmConsolePermissions = new ArrayList<String>();
this.getAuthorizedPermissions(emmRolePermissions, emmConsolePermissions); this.getAuthorizedPermissions(emmRolePermissions, emmConsolePermissions);
emmConsolePermissions.removeAll(new ArrayList<String>(Arrays.asList(roleInfo.getPermissions()))); emmConsolePermissions.removeAll(new ArrayList<String>(Arrays.asList(roleInfo.getPermissions())));
@ -413,7 +438,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
permissions.add(permission); permissions.add(permission);
} }
permissions.removeAll(emmConsolePermissions); permissions.removeAll(emmConsolePermissions);
String [] allApplicablePerms = new String[permissions.size()]; String[] allApplicablePerms = new String[permissions.size()];
allApplicablePerms = permissions.toArray(allApplicablePerms); allApplicablePerms = permissions.toArray(allApplicablePerms);
roleInfo.setPermissions(allApplicablePerms); roleInfo.setPermissions(allApplicablePerms);
@ -428,7 +453,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
} }
//TODO: Need to send the updated role information in the entity back to the client //TODO: Need to send the updated role information in the entity back to the client
return Response.status(Response.Status.OK).entity("Role '" + roleInfo.getRoleName() + "' has " + return Response.status(Response.Status.OK).entity("Role '" + roleInfo.getRoleName() + "' has " +
"successfully been updated").build(); "successfully been updated").build();
} catch (UserStoreException e) { } catch (UserStoreException e) {
String msg = "Error occurred while updating role '" + roleName + "'"; String msg = "Error occurred while updating role '" + roleName + "'";
log.error(msg, e); log.error(msg, e);
@ -456,7 +481,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
if (!userStoreManager.isExistingRole(roleName)) { if (!userStoreManager.isExistingRole(roleName)) {
return Response.status(404).entity( return Response.status(404).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" +
roleName + "'").build()).build(); roleName + "'").build()).build();
} }
final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager(); final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager();
@ -493,7 +518,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
} }
SetReferenceTransformer<String> transformer = new SetReferenceTransformer<>(); SetReferenceTransformer<String> transformer = new SetReferenceTransformer<>();
transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(roleName)), transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(roleName)),
users); users);
final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer
.getObjectsToAdd().size()]); .getObjectsToAdd().size()]);
final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer
@ -502,7 +527,7 @@ public class RoleManagementServiceImpl implements RoleManagementService {
userStoreManager.updateUserListOfRole(roleName, usersToDelete, usersToAdd); userStoreManager.updateUserListOfRole(roleName, usersToDelete, usersToAdd);
return Response.status(Response.Status.OK).entity("Role '" + roleName + "' has " + return Response.status(Response.Status.OK).entity("Role '" + roleName + "' has " +
"successfully been updated with the user list") "successfully been updated with the user list")
.build(); .build();
} catch (UserStoreException e) { } catch (UserStoreException e) {
String msg = "Error occurred while updating the users of the role '" + roleName + "'"; String msg = "Error occurred while updating the users of the role '" + roleName + "'";

@ -1,5 +1,5 @@
{ {
"appName": "WSO2 IoT Server", "appName": "WSO2 Device Cloud",
"cachingEnabled": false, "cachingEnabled": false,
"debuggingEnabled": false, "debuggingEnabled": false,
"permissionRoot": "/", "permissionRoot": "/",

@ -98,6 +98,26 @@ deviceModule = function () {
locationTimeData.push(gpsReadingTimes); locationTimeData.push(gpsReadingTimes);
} }
} }
var locationInfo = {};
try {
var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId + "/location";
serviceInvokers.XMLHttp.get(
url,
function (backendResponse) {
if (backendResponse.status == 200 && backendResponse.responseText) {
var device = parse(backendResponse.responseText);
locationInfo.latitude = device.latitude;
locationInfo.longitude = device.longitude;
locationInfo.updatedOn = device.updatedTime;
}
});
} catch (e) {
log.error(e.message, e);
}
var utility = require('/app/modules/utility.js')["utility"]; var utility = require('/app/modules/utility.js')["utility"];
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
@ -174,11 +194,26 @@ deviceModule = function () {
} }
if (device["deviceInfo"]) { if (device["deviceInfo"]) {
filteredDeviceData["latestDeviceInfo"] = device["deviceInfo"]; filteredDeviceData["latestDeviceInfo"] = device["deviceInfo"];
//location related verification and modifications
// adding the location histry for the movement path.
var locationHistory = {};
locationHistory.locations = locationData;
locationHistory.times = locationTimeData;
filteredDeviceData["locationHistory"] = locationHistory;
//checking for the latest location information.
if (filteredDeviceData.latestDeviceInfo.location && locationInfo) {
var infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime);
var locationDate = new Date(locationInfo.updatedOn);
if (infoDate < locationDate) {
filteredDeviceData.latestDeviceInfo.location.longitude = locationInfo.longitude;
filteredDeviceData.latestDeviceInfo.location.latitude = locationInfo.latitude;
}
}
} }
var locationHistory = {};
locationHistory.locations = locationData;
locationHistory.times = locationTimeData;
filteredDeviceData["locationHistory"] = locationHistory;
response["content"] = filteredDeviceData; response["content"] = filteredDeviceData;
response["status"] = "success"; response["status"] = "success";
return response; return response;

@ -302,6 +302,32 @@ var userModule = function () {
} }
}; };
/**
* Get User Roles from user store (Internal roles not included).
*/
publicMethods.getFilteredRoles = function (prefix) {
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
var utility = require("/app/modules/utility.js")["utility"];
if (!carbonUser) {
log.error("User object was not found in the session");
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
try {
utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/roles/filter/" + prefix + "?offset=0&limit=100&user-store=all";
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") {
response.content = parse(response.content);
}
return response;
} catch (e) {
throw e;
} finally {
utility.endTenantFlow();
}
};
/** /**
* Get User Roles count from user store (Internal roles not included). * Get User Roles count from user store (Internal roles not included).
*/ */
@ -467,8 +493,8 @@ var userModule = function () {
try { try {
carbonUser = session.get(constants.USER_SESSION_KEY); carbonUser = session.get(constants.USER_SESSION_KEY);
} catch (e) { } catch (e) {
log.error("User object was not found in the session"); log.error("User object was not found in the session");
carbonUser = null; carbonUser = null;
} }
var utility = require('/app/modules/utility.js').utility; var utility = require('/app/modules/utility.js').utility;
if (!carbonUser) { if (!carbonUser) {

@ -39,8 +39,8 @@ utility = function () {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
context = PrivilegedCarbonContext.getThreadLocalCarbonContext(); context = PrivilegedCarbonContext.getThreadLocalCarbonContext();
context.setTenantDomain(carbon.server.tenantDomain({ context.setTenantDomain(carbon.server.tenantDomain({
tenantId: userInfo.tenantId tenantId: userInfo.tenantId
})); }));
context.setTenantId(userInfo.tenantId); context.setTenantId(userInfo.tenantId);
context.setUsername(userInfo.username || null); context.setUsername(userInfo.username || null);
}; };
@ -161,15 +161,19 @@ utility = function () {
* @returns {*} * @returns {*}
*/ */
publicMethods.encodeJson = function (text) { publicMethods.encodeJson = function (text) {
return text if (text) {
.replace(/\\u003c/g, "&lt;") return text
.replace(/</g, "&lt;") .replace(/\\u003c/g, "&lt;")
.replace(/\\u003e/g, "&gt;") .replace(/</g, "&lt;")
.replace(/>/g, "&gt;") .replace(/\\u003e/g, "&gt;")
.replace(/\\u0027/g, "&#39;") .replace(/>/g, "&gt;")
.replace(/'/g, "&#39;") .replace(/\\u0027/g, "&#39;")
.replace(/\\"/g, "&quot;") .replace(/'/g, "&#39;")
.replace(/\\u0022/g, "&quot;") .replace(/\\"/g, "&quot;")
.replace(/\\u0022/g, "&quot;");
} else {
return "";
}
}; };
return publicMethods; return publicMethods;

@ -39,8 +39,11 @@ function onRequest() {
viewModel.groupCount = groupModule.getGroupCount(); viewModel.groupCount = groupModule.getGroupCount();
viewModel.userCount = userModule.getUsersCount(); viewModel.userCount = userModule.getUsersCount();
viewModel.policyCount = policyModule.getPoliciesCount(); viewModel.policyCount = policyModule.getPoliciesCount();
viewModel.roleCount = userModule.getRolesCount();
viewModel.isCloud = devicemgtProps.isCloud; viewModel.isCloud = devicemgtProps.isCloud;
if (devicemgtProps.isCloud) {
viewModel.roleCount = userModule.getFilteredRoles("devicemgt").content.count;
} else {
viewModel.roleCount = userModule.getRolesCount();
}
return viewModel; return viewModel;
} }

@ -98,42 +98,22 @@ function loadRoles() {
var dataFilter = function (data) { var dataFilter = function (data) {
data = JSON.parse(data); data = JSON.parse(data);
var objects = []; var objects = [];
var count = 0; var count = 0;
$(data.roles).each(function (index) { $(data.roles).each(function (index) {
if (isCloud && data.roles[index].startsWith("devicemgt")) { objects.push(
count++; {
objects.push( name: htmlspecialchars(data.roles[index]),
{ DT_RowId: "role-" + htmlspecialchars(data.roles[index])
name: htmlspecialchars(data.roles[index]), }
DT_RowId: "role-" + htmlspecialchars(data.roles[index]) )
}
)
} else if (!isCloud) {
objects.push(
{
name: htmlspecialchars(data.roles[index]),
DT_RowId: "role-" + htmlspecialchars(data.roles[index])
}
)
}
}); });
var json = {}; var json = {
if (isCloud) { "recordsTotal": data.count,
json = { "recordsFiltered": data.count,
"recordsTotal": count, "data": objects
"recordsFiltered": count, };
"data": objects
};
} else {
json = {
"recordsTotal": data.count,
"recordsFiltered": data.count,
"data": objects
};
}
return JSON.stringify(json); return JSON.stringify(json);
}; };
@ -156,7 +136,7 @@ function loadRoles() {
class: "", class: "",
data: "name", data: "name",
render: function (name, type, row, meta) { render: function (name, type, row, meta) {
return '<h4>' + name + '</h4>'; return '<h4>' + name.replace("devicemgt", ""); + '</h4>';
} }
}, },
{ {
@ -225,8 +205,12 @@ function loadRoles() {
var settings = { var settings = {
"sorting": false "sorting": false
}; };
var roleApiUrl = '/api/device-mgt/v1.0/roles?user-store=all';
if (isCloud) {
roleApiUrl = '/api/device-mgt/v1.0/roles/filter/devicemgt?user-store=all';
}
$('#role-grid').datatables_extended_serverside_paging(settings, '/api/device-mgt/v1.0/roles?user-store=all', dataFilter, columns, fnCreatedRow, null, options); $('#role-grid').datatables_extended_serverside_paging(settings, roleApiUrl, dataFilter, columns, fnCreatedRow, null, options);
loadingContent.hide(); loadingContent.hide();
} }

@ -50,45 +50,66 @@
{{/zone}} {{/zone}}
{{#zone "content"}} {{#zone "content"}}
<div id="loading-content" class="col-centered"> {{#if hasRoles}}
{{#unless isCloud}} <div id="loading-content" class="col-centered">
{{#if removePermitted}} {{#unless isCloud}}
<input type="hidden" id="can-remove" value="true"/> {{#if removePermitted}}
<input type="hidden" id="can-remove" value="true"/>
{{/if}}
{{#if editPermitted}}
<input type="hidden" id="can-edit" value="true"/>
{{/if}}
{{/unless}}
{{#if isCloud}}
<input type="hidden" id="is-cloud" value="true"/>
{{/if}} {{/if}}
{{#if editPermitted}} <i class="fw fw-settings fw-spin fw-2x"></i>
<input type="hidden" id="can-edit" value="true"/> Loading roles . . .
{{/if}} <br>
{{/unless}} </div>
{{#if isCloud}}
<input type="hidden" id="is-cloud" value="true"/> <div id="role-table" data-cloud={{isCloud}} data-role={{adminRole}}>
{{/if}} <table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view"
<i class="fw fw-settings fw-spin fw-2x"></i> id="role-grid">
Loading roles . . . <thead>
<br> <tr class="sort-row">
</div> <th>By Role Name</th>
</tr>
<tr class="bulk-action-row">
<th colspan="3"></th>
</tr>
</thead>
<tbody id="ast-container" data-app-context="{{@app.context}}/"></tbody>
</table>
</div>
<div id="role-table" data-cloud={{isCloud}} data-role={{adminRole}}> <div id="content-filter-types" style="display: none">
<table class="table table-striped table-hover list-table display responsive nowrap data-table grid-view" <div class="sort-title">Sort By</div>
id="role-grid"> <div class="sort-options">
<thead> <!--suppress HtmlUnknownTag -->
<tr class="sort-row"> <th>By Role name</th>
<th>By Role Name</th> </div>
</tr> </div>
<tr class="bulk-action-row">
<th colspan="3"></th> {{else}}
</tr>
</thead>
<tbody id="ast-container" data-app-context="{{@app.context}}/"></tbody>
</table>
</div>
<div id="content-filter-types" style="display: none"> <div id="user-created-msg" class="container col-centered wr-content">
<div class="sort-title">Sort By</div> <div class="wr-form">
<div class="sort-options"> <p class="page-sub-title">You Haven't created roles yet.</p>
<!--suppress HtmlUnknownTag --> <br>Please click <b>"Add A New Role"</b>, if you wish to add a role.
<th>By Role name</th> <hr/>
<a href="{{@app.context}}/role/add" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add Role
</a>
</div>
</div> </div>
</div>
{{/if}}
{{/zone}} {{/zone}}
{{#zone "bottomJs"}} {{#zone "bottomJs"}}

@ -33,6 +33,16 @@ function onRequest(context) {
context["adminRole"] = deviceMgtProps["adminRole"]; context["adminRole"] = deviceMgtProps["adminRole"];
context["isCloud"] = deviceMgtProps["isCloud"]; context["isCloud"] = deviceMgtProps["isCloud"];
var roleCount = userModule.getRolesCount()
if (deviceMgtProps["isCloud"]) {
roleCount = userModule.getFilteredRoles("devicemgt").content.count;
}
if (roleCount > 0) {
context["hasRoles"] = true;
} else {
context["hasRoles"] = false;
}
return context; return context;
} }

@ -37,99 +37,100 @@
{{#zone "content"}} {{#zone "content"}}
{{#if canView}} {{#if canView}}
{{#zone "contentTitle"}} {{#if exists}}
<div class="row wr-device-board"> {{#zone "contentTitle"}}
<div class="col-lg-12 wr-secondary-bar"> <div class="row wr-device-board">
<label class="device-id device-select" data-username="{{user.username}}"> <div class="col-lg-12 wr-secondary-bar">
{{#if user.firstname}} <label class="device-id device-select" data-username="{{user.username}}">
{{user.firstname}} {{user.lastname}} {{#if user.firstname}}
{{else}} {{user.firstname}} {{user.lastname}}
{{user.username}} {{else}}
{{/if}} {{user.username}}
</label> {{/if}}
</label>
</div>
</div> </div>
</div> {{/zone}}
{{/zone}}
<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 class="media-left media-middle asset-image col-xs-2 col-sm-2 col-md-2 col-lg-2">
<div class="thumbnail icon" style="margin-bottom: 43px"><i <div class="thumbnail icon" style="margin-bottom: 43px"><i
class="square-element text fw fw-user"></i> class="square-element text fw fw-user"></i>
</div> </div>
<div class="media"> <div class="media">
{{#unless isCloud}} {{#unless isCloud}}
{{#if editPermitted}} {{#if editPermitted}}
<button class="wr-btn" <button class="wr-btn"
onclick="location.href='{{@app.context}}/users/edit-user?username={{user.username}}';" onclick="location.href='{{@app.context}}/users/edit-user?username={{user.username}}';"
id="sortUpdateBtn" id="sortUpdateBtn"
style="width: 100%; vertical-align: bottom; background-color: #7fa030;"><span><i style="width: 100%; vertical-align: bottom; background-color: #7fa030;"><span><i
class="fw fw-edit"></i> Edit</span></button> class="fw fw-edit"></i> Edit</span></button>
{{/if}} {{/if}}
{{/unless}} {{/unless}}
</div>
</div> </div>
</div> <div class="media-body asset-desc add-padding-left-5x">
<div class="media-body asset-desc add-padding-left-5x"> <div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Profile Overview
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Profile Overview </div>
{{#defineZone "user-detail-properties"}}
<table class="table table-responsive table-striped" id="members">
<tbody>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 7%;">Username</td>
<td style="padding:10px 15px;">{{user.username}}</td>
</tr>
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">First Name</td>
<td style="padding:10px 15px;">{{user.firstname}}</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Last Name</td>
<td style="padding:10px 15px;">{{user.lastname}}</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Email</td>
<td style="padding:10px 15px;">{{user.emailAddress}}</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Roles</td>
<td style="padding:10px 15px;">
{{#each userRoles}}
<option selected="selected">{{this}}</option>
{{/each}}
</td>
</tr>
</tbody>
</table>
{{/defineZone}}
</div> </div>
{{#defineZone "user-detail-properties"}}
<table class="table table-responsive table-striped" id="members">
<tbody>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 7%;">Username</td>
<td style="padding:10px 15px;">{{user.username}}</td>
</tr>
<tr role="row" class="odd">
<td class="sorting_1" style="padding:10px 15px;">First Name</td>
<td style="padding:10px 15px;">{{user.firstname}}</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Last Name</td>
<td style="padding:10px 15px;">{{user.lastname}}</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Email</td>
<td style="padding:10px 15px;">{{user.emailAddress}}</td>
</tr>
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px;">Roles</td>
<td style="padding:10px 15px;">
{{#each userRoles}}
<option>{{this}}</option>
{{/each}}
</td>
</tr>
</tbody>
</table>
{{/defineZone}}
</div>
</div>
<div class="media">
<div class="media-left col-xs-12 col-sm-2 col-md-2 col-lg-2">
<ul class="list-group" role="tablist">
<li class="active"><a class="list-group-item" href="#enrolled_devices" role="tab"
data-toggle="tab" aria-controls="enrolled_devices">Enrolled Devices</a>
</li>
</ul>
</div> </div>
{{#defineZone "user-enrolled-devices"}} <div class="media">
<div class="media-body add-padding-left-5x remove-padding-xs tab-content"> <div class="media-left col-xs-12 col-sm-2 col-md-2 col-lg-2">
<div class="panel-group tab-content"> <ul class="list-group" role="tablist">
<div class="panel panel-default tab-pane active" id="enrolled_devices" <li class="active"><a class="list-group-item" href="#enrolled_devices" role="tab"
role="tabpanel" aria-labelledby="enrolled_devices"> data-toggle="tab" aria-controls="enrolled_devices">Enrolled Devices</a>
<div class="panel-heading">Enrolled Devices by </li>
{{#if user.firstname}} </ul>
{{user.firstname}} {{user.lastname}} </div>
{{else}} {{#defineZone "user-enrolled-devices"}}
{{user.username}} <div class="media-body add-padding-left-5x remove-padding-xs tab-content">
{{/if}} <div class="panel-group tab-content">
</div> <div class="panel panel-default tab-pane active" id="enrolled_devices"
<div class="panel-body"> role="tabpanel" aria-labelledby="enrolled_devices">
<div id="enrolled_devices-container"> <div class="panel-heading">Enrolled Devices by
<div class="panel-body"> {{#if user.firstname}}
{{#each devices}} {{user.firstname}} {{user.lastname}}
<div class="wr-list-group wr-sortable policy-list"> {{else}}
{{user.username}}
{{/if}}
</div>
<div class="panel-body">
<div id="enrolled_devices-container">
<div class="panel-body">
{{#each devices}}
<div class="wr-list-group wr-sortable policy-list">
<span class="list-group-item" id="{{id}}"> <span class="list-group-item" id="{{id}}">
<div class="row"> <div class="row">
<div class="col-lg-3 clearfix"> <div class="col-lg-3 clearfix">
@ -160,18 +161,37 @@
</div> </div>
</div> </div>
</span> </span>
</div> </div>
{{/each}} {{/each}}
</div>
<br class="c-both"/>
</div> </div>
<br class="c-both"/>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> {{/defineZone}}
{{/defineZone}} </div>
</div>
{{else}}
<div id="user-created-msg" class="container col-centered wr-content">
<div class="wr-form">
<p class="page-sub-title">User not found.</p>
<br>Please click <b>"Add A New User"</b>, if you wish to add user or click
<b>"View User List"</b> to navigate to the user list.
<hr/>
<button class="wr-btn" onclick="window.location.href='{{@app.context}}/users'">View User List
</button>
<a href="{{@app.context}}/user/add" class="cu-btn-inner">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-add fw-stack-1x"></i>
</span>
Add Another User
</a>
</div>
</div> </div>
</div> {{/if}}
{{else}} {{else}}
<h1 class="page-sub-title"> <h1 class="page-sub-title">
Permission Denied Permission Denied

@ -21,7 +21,7 @@ function onRequest(context) {
var username = request.getParameter("username"); var username = request.getParameter("username");
var user = userModule.getUser(username)["content"]; var user = userModule.getUser(username)["content"];
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var isExsistingUser = false;
var userName = request.getParameter("username"); var userName = request.getParameter("username");
var user, userRoles, devices; var user, userRoles, devices;
@ -32,6 +32,7 @@ function onRequest(context) {
if (response["status"] == "success") { if (response["status"] == "success") {
user = response["content"]; user = response["content"];
user.domain = response["userDomain"]; user.domain = response["userDomain"];
isExsistingUser = true;
} }
response = userModule.getRolesByUsername(userName); response = userModule.getRolesByUsername(userName);
@ -49,5 +50,5 @@ function onRequest(context) {
var isCloud = deviceMgtProps.isCloud; var isCloud = deviceMgtProps.isCloud;
return {"user": user, "userRoles": userRoles, "devices": devices, "canView": canView, "isCloud" : isCloud}; return {"exists": isExsistingUser, "user": user, "userRoles": userRoles, "devices": devices, "canView": canView, "isCloud" : isCloud};
} }

Loading…
Cancel
Save