|
|
@ -21,7 +21,6 @@ package org.wso2.carbon.mdm.services.android.services.impl;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
|
|
|
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
|
|
|
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
|
|
|
|
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
|
|
|
|
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
|
|
|
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
|
|
@ -78,9 +77,7 @@ import java.net.URL;
|
|
|
|
import java.net.URLConnection;
|
|
|
|
import java.net.URLConnection;
|
|
|
|
import java.text.ParseException;
|
|
|
|
import java.text.ParseException;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Path("/admin/devices")
|
|
|
|
@Path("/admin/devices")
|
|
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
|
@ -88,7 +85,7 @@ import java.util.Map;
|
|
|
|
public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService {
|
|
|
|
public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService {
|
|
|
|
|
|
|
|
|
|
|
|
private static final Log log = LogFactory.getLog(DeviceManagementAdminServiceImpl.class);
|
|
|
|
private static final Log log = LogFactory.getLog(DeviceManagementAdminServiceImpl.class);
|
|
|
|
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
|
|
|
|
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
|
|
|
|
|
|
|
|
|
|
|
|
@POST
|
|
|
|
@POST
|
|
|
|
@Path("/lock-devices")
|
|
|
|
@Path("/lock-devices")
|
|
|
@ -534,59 +531,16 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
throw new BadRequestException(
|
|
|
|
throw new BadRequestException(
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String scheduledTime = applicationInstallationBeanWrapper.getOperation().getSchedule();
|
|
|
|
|
|
|
|
if (scheduledTime != null && !scheduledTime.isEmpty()) {
|
|
|
|
|
|
|
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
String formattedScheduledDate = format.format(format.parse(scheduledTime));
|
|
|
|
|
|
|
|
applicationInstallationBeanWrapper.getOperation().setSchedule(formattedScheduledDate);
|
|
|
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Invalid date string is provided in for schedule parameter";
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ApplicationInstallation applicationInstallation = applicationInstallationBeanWrapper.getOperation();
|
|
|
|
ApplicationInstallation applicationInstallation = applicationInstallationBeanWrapper.getOperation();
|
|
|
|
JSONObject payload = new JSONObject(applicationInstallation.toJSON());
|
|
|
|
validateApplicationUrl(applicationInstallation.getUrl());
|
|
|
|
|
|
|
|
validateApplicationType(applicationInstallation.getType());
|
|
|
|
try {
|
|
|
|
validateScheduleDate(applicationInstallation.getSchedule());
|
|
|
|
URL url = new URL(payload.getString("url"));
|
|
|
|
|
|
|
|
URLConnection conn = url.openConnection();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//get all headers
|
|
|
|
|
|
|
|
Map<String, List<String>> headerFields = conn.getHeaderFields();
|
|
|
|
|
|
|
|
boolean isFile = false;
|
|
|
|
|
|
|
|
for (Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
|
|
|
|
|
|
|
|
if ("Content-Type".equals(entry.getKey()) && entry.getValue() != null
|
|
|
|
|
|
|
|
&& entry.getValue().size() > 0 && "application/octet-stream".equals(entry.getValue().get(0))) {
|
|
|
|
|
|
|
|
isFile = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isFile) {
|
|
|
|
|
|
|
|
String errorMessage = "URL is not pointed to a downloadable file.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
validateType(payload);
|
|
|
|
|
|
|
|
} catch (MalformedURLException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Malformed application url.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Invalid application url.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.INSTALL_APPLICATION);
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.INSTALL_APPLICATION);
|
|
|
|
operation.setType(Operation.Type.PROFILE);
|
|
|
|
operation.setType(Operation.Type.PROFILE);
|
|
|
|
operation.setPayLoad(payload.toString());
|
|
|
|
operation.setPayLoad(applicationInstallation.toJSON());
|
|
|
|
return AndroidAPIUtils.getOperationResponse(applicationInstallationBeanWrapper.getDeviceIDs(),
|
|
|
|
return AndroidAPIUtils.getOperationResponse(applicationInstallationBeanWrapper.getDeviceIDs(),
|
|
|
|
operation);
|
|
|
|
operation);
|
|
|
|
} catch (JSONException e) {
|
|
|
|
} catch (JSONException e) {
|
|
|
@ -627,19 +581,11 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
throw new BadRequestException(
|
|
|
|
throw new BadRequestException(
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String scheduledTime = applicationUpdateBeanWrapper.getOperation().getSchedule();
|
|
|
|
|
|
|
|
if (scheduledTime != null && !scheduledTime.isEmpty()) {
|
|
|
|
|
|
|
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
String formattedScheduledDate = format.format(format.parse(scheduledTime));
|
|
|
|
|
|
|
|
applicationUpdateBeanWrapper.getOperation().setSchedule(formattedScheduledDate);
|
|
|
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Invalid date string is provided in for schedule parameter";
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ApplicationUpdate applicationUpdate = applicationUpdateBeanWrapper.getOperation();
|
|
|
|
ApplicationUpdate applicationUpdate = applicationUpdateBeanWrapper.getOperation();
|
|
|
|
|
|
|
|
validateApplicationUrl(applicationUpdate.getUrl());
|
|
|
|
|
|
|
|
validateApplicationType(applicationUpdate.getType());
|
|
|
|
|
|
|
|
validateScheduleDate(applicationUpdate.getSchedule());
|
|
|
|
|
|
|
|
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.UPDATE_APPLICATION);
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.UPDATE_APPLICATION);
|
|
|
|
operation.setType(Operation.Type.PROFILE);
|
|
|
|
operation.setType(Operation.Type.PROFILE);
|
|
|
@ -682,8 +628,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ApplicationUninstallation applicationUninstallation = applicationUninstallationBeanWrapper.getOperation();
|
|
|
|
ApplicationUninstallation applicationUninstallation = applicationUninstallationBeanWrapper.getOperation();
|
|
|
|
JSONObject payload = new JSONObject(applicationUninstallation.toJSON());
|
|
|
|
validateApplicationType(applicationUninstallation.getType());
|
|
|
|
validateType(payload);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.UNINSTALL_APPLICATION);
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.UNINSTALL_APPLICATION);
|
|
|
@ -710,25 +655,6 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void validateType(JSONObject payload) {
|
|
|
|
|
|
|
|
if (payload.has("type")) {
|
|
|
|
|
|
|
|
String type = payload.getString("type");
|
|
|
|
|
|
|
|
if (!"enterprise".equalsIgnoreCase(type)
|
|
|
|
|
|
|
|
&& !"public".equalsIgnoreCase(type)
|
|
|
|
|
|
|
|
&& !"webapp".equalsIgnoreCase(type)) {
|
|
|
|
|
|
|
|
String errorMessage = "Invalid application type.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
String errorMessage = "Application type is missing.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@POST
|
|
|
|
@POST
|
|
|
|
@Path("/blacklist-applications")
|
|
|
|
@Path("/blacklist-applications")
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
@ -785,13 +711,7 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UpgradeFirmware upgradeFirmware = upgradeFirmwareBeanWrapper.getOperation();
|
|
|
|
UpgradeFirmware upgradeFirmware = upgradeFirmwareBeanWrapper.getOperation();
|
|
|
|
|
|
|
|
validateScheduleDate(upgradeFirmware.getSchedule());
|
|
|
|
//validate date
|
|
|
|
|
|
|
|
if(upgradeFirmware != null && upgradeFirmware.getSchedule() != null){
|
|
|
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
|
|
|
|
|
|
|
|
sdf.setLenient(false);
|
|
|
|
|
|
|
|
Date date = sdf.parse(upgradeFirmware.getSchedule());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
ProfileOperation operation = new ProfileOperation();
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.UPGRADE_FIRMWARE);
|
|
|
|
operation.setCode(AndroidConstants.OperationCodes.UPGRADE_FIRMWARE);
|
|
|
@ -813,11 +733,6 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
log.error(errorMessage, e);
|
|
|
|
log.error(errorMessage, e);
|
|
|
|
throw new UnexpectedServerErrorException(
|
|
|
|
throw new UnexpectedServerErrorException(
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build());
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build());
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Issue in validating the schedule date";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1103,4 +1018,71 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static boolean hasValidAPKContentType(String contentType){
|
|
|
|
|
|
|
|
if (contentType != null){
|
|
|
|
|
|
|
|
switch (contentType) {
|
|
|
|
|
|
|
|
case MediaType.APPLICATION_OCTET_STREAM:
|
|
|
|
|
|
|
|
case "application/android":
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void validateApplicationUrl(String apkUrl) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
URL url = new URL(apkUrl);
|
|
|
|
|
|
|
|
URLConnection conn = url.openConnection();
|
|
|
|
|
|
|
|
if (!hasValidAPKContentType(conn.getContentType())) {
|
|
|
|
|
|
|
|
String errorMessage = "URL is not pointed to a downloadable file.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (MalformedURLException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Malformed application url.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Invalid application url.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void validateApplicationType(String type) {
|
|
|
|
|
|
|
|
if (type != null) {
|
|
|
|
|
|
|
|
if (!"enterprise".equalsIgnoreCase(type)
|
|
|
|
|
|
|
|
&& !"public".equalsIgnoreCase(type)
|
|
|
|
|
|
|
|
&& !"webapp".equalsIgnoreCase(type)) {
|
|
|
|
|
|
|
|
String errorMessage = "Invalid application type.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
String errorMessage = "Application type is missing.";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void validateScheduleDate(String dateString){
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (dateString != null) {
|
|
|
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
|
|
|
|
|
|
|
|
sdf.setLenient(false);
|
|
|
|
|
|
|
|
sdf.parse(dateString);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
|
|
|
String errorMessage = "Issue in validating the schedule date";
|
|
|
|
|
|
|
|
log.error(errorMessage);
|
|
|
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
|
|
|
new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|