Fix google enterprise API invoking issue

merge-requests/131/head
lasanthaDLPDS 5 years ago
parent 43147d600b
commit 343736d36b

@ -251,7 +251,6 @@
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidenterprise</artifactId>
<version>v1-rev186-1.25.0</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
@ -318,6 +317,12 @@
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>org.wso2.carbon.device.mgt.mobile.android.common</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>google-api-services-androidenterprise</artifactId>
<groupId>com.google.apis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>

@ -43,7 +43,6 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.mobile.android.api.AndroidEnterpriseAPI;
import org.wso2.carbon.device.mgt.mobile.android.common.AndroidConstants;
import org.wso2.carbon.device.mgt.mobile.android.common.GoogleAPIInvoker;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.EnterpriseConfigs;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.EnterpriseStoreCluster;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.EnterpriseStorePackages;
@ -65,6 +64,7 @@ import org.wso2.carbon.device.mgt.mobile.android.common.exception.UnexpectedServ
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidAPIUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidDeviceUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidEnterpriseUtils;
import org.wso2.carbon.device.mgt.mobile.android.api.invoker.GoogleAPIInvoker;
import org.wso2.carbon.policy.mgt.common.FeatureManagementException;
import javax.ws.rs.Consumes;
@ -146,7 +146,7 @@ public class AndroidEnterpriseAPIImpl implements AndroidEnterpriseAPI {
List<AndroidEnterpriseUser> androidEnterpriseUsers = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUser(CarbonContext.getThreadLocalCarbonContext().getUsername());
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
if (androidEnterpriseUsers != null && androidEnterpriseUsers.size() > 0) {
if (androidEnterpriseUsers != null && !androidEnterpriseUsers.isEmpty()) {
googleUserId = androidEnterpriseUsers.get(0).getGoogleUserId();
// If this device is also present, only need to provide a token for this request.
for (AndroidEnterpriseUser enterprise : androidEnterpriseUsers) {

@ -35,22 +35,39 @@
package org.wso2.carbon.device.mgt.mobile.android.api.impl;
import com.google.api.client.http.HttpStatusCodes;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.application.mgt.common.SubAction;
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.device.mgt.mobile.android.api.DeviceManagementAPI;
import org.wso2.carbon.device.mgt.mobile.android.api.invoker.GoogleAPIInvoker;
import org.wso2.carbon.device.mgt.mobile.android.common.AndroidConstants;
import org.wso2.carbon.device.mgt.mobile.android.common.AndroidPluginConstants;
import org.wso2.carbon.device.mgt.mobile.android.common.Message;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.EnterpriseConfigs;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.ErrorResponse;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.AndroidApplication;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.AndroidDevice;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.EnterpriseApp;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.EnterpriseInstallPolicy;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.EnterpriseUser;
import org.wso2.carbon.device.mgt.mobile.android.common.dto.AndroidEnterpriseUser;
import org.wso2.carbon.device.mgt.mobile.android.common.exception.*;
import org.wso2.carbon.device.mgt.mobile.android.common.spi.AndroidService;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidAPIUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidDeviceUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidEnterpriseUtils;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
@ -68,6 +85,8 @@ 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.Arrays;
import java.util.List;
@Path("/devices")
@ -112,8 +131,12 @@ public class DeviceManagementAPIImpl implements DeviceManagementAPI {
}
try {
AndroidService androidService = AndroidAPIUtils.getAndroidService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(id);
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(id, resultOperations, disableGoogleApps);
.getPendingOperations(deviceIdentifier, resultOperations);
if (pendingOperations != null && !disableGoogleApps) {
handleEnrollmentGoogleApps(pendingOperations, deviceIdentifier);
}
return Response.status(Response.Status.CREATED).entity(pendingOperations).build();
} catch (InvalidDeviceException e) {
String msg = "Device identifier is invalid. Device identifier " + id;
@ -146,7 +169,33 @@ public class DeviceManagementAPIImpl implements DeviceManagementAPI {
}
try {
AndroidService androidService = AndroidAPIUtils.getAndroidService();
String token = null;
String googleEMMAndroidId = null;
String googleEMMDeviceId = null;
if (androidDevice.getProperties() != null) {
for (Device.Property property : androidDevice.getProperties()) {
if (property.getName().equals(AndroidPluginConstants.GOOGLE_AFW_EMM_ANDROID_ID)) {
googleEMMAndroidId = property.getValue();
} else if (property.getName().equals(AndroidPluginConstants.GOOGLE_AFW_DEVICE_ID)) {
googleEMMDeviceId = property.getValue();
}
}
if (googleEMMAndroidId != null && googleEMMDeviceId != null) {
EnterpriseUser user = new EnterpriseUser();
user.setAndroidPlayDeviceId(googleEMMAndroidId);
user.setEmmDeviceIdentifier(googleEMMDeviceId);
try {
AndroidEnterpriseAPIImpl enterpriseService = new AndroidEnterpriseAPIImpl();
token = enterpriseService.insertUser(user);
} catch (EnterpriseServiceException e) {
//todo
}
}
}
Message message = androidService.enrollDevice(androidDevice);
if (token != null) {
message.setResponseMessage("Google response token" + token);
}
return Response.status(Integer.parseInt(message.getResponseCode()))
.entity(message.getResponseMessage()).build();
} catch (DeviceManagementException e) {
@ -258,5 +307,96 @@ public class DeviceManagementAPIImpl implements DeviceManagementAPI {
}
}
private void handleEnrollmentGoogleApps(List<? extends Operation> operations, DeviceIdentifier
deviceIdentifier) {
boolean containsGoogleAppPolicy = false;
for (int x = 0; x < operations.size() && !containsGoogleAppPolicy; x++) {
Operation operation = operations.get(x);
// Check if the operation has a policy bundle inside.
if (operation.getCode().equals(AndroidConstants.OperationCodes.POLICY_BUNDLE)) {
ArrayList operationPayLoad = (ArrayList) operation.getPayLoad();
// If there is a policy bundle, read its payload
for (int i = 0; i < operationPayLoad.size() && !containsGoogleAppPolicy; i++) {
Object policy = operationPayLoad.get(i);
ProfileOperation profileOperation = (ProfileOperation) policy;
String code = profileOperation.getCode();
// Find if there is an ENROLLMENT_APP_INSTALL payload
if (code.equals(AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_FEATURE_CODE)) {
String payload = profileOperation.getPayLoad().toString();
JsonElement appListElement = new JsonParser().parse(payload).getAsJsonObject()
.get(AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_CODE);
JsonArray appListArray = appListElement.getAsJsonArray();
// Find if there are Apps with Work profile configurations
boolean alreadySendToGoogle = false;
for (JsonElement appElement : appListArray) {
JsonElement googlePolicyPayload = appElement.getAsJsonObject().
get(AndroidConstants.ApplicationInstall.GOOGLE_POLICY_PAYLOAD);
if (googlePolicyPayload != null) {
String uuid = appElement.getAsJsonObject().get("uuid").toString();
containsGoogleAppPolicy = true;// breaking out of outer for loop
try {
uuid = uuid.replace("\"", "");
if (alreadySendToGoogle) {
sendPayloadToGoogle(uuid, payload, deviceIdentifier, false);
} else {
sendPayloadToGoogle(uuid, payload, deviceIdentifier, true);
alreadySendToGoogle = true;
}
} catch (org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException e) {
String errorMessage = "App install failed for device " + deviceIdentifier.getId();
log.error(errorMessage, e);
}
}
}
}
}
}
}
}
/**
* Sends the app install policy to Google
* @param payload policy profile
* @param deviceIdentifier device to apply policy
*/
private void sendPayloadToGoogle(String uuid, String payload, DeviceIdentifier deviceIdentifier,
boolean requireSendingToGoogle) throws
org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException {
try {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigsFromGoogle();
if (enterpriseConfigs.getErrorResponse() == null) {
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
AndroidEnterpriseUser userDetail = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUserByDevice(deviceIdentifier.getId());
if (userDetail != null && userDetail.getEnterpriseId() != null && !userDetail.getEnterpriseId()
.isEmpty() && userDetail.getEmmUsername() != null && payload != null) {
EnterpriseInstallPolicy enterpriseInstallPolicy = AndroidEnterpriseUtils
.getDeviceAppPolicy(payload, null, userDetail);
List<String> apps = new ArrayList<>();
for (EnterpriseApp enterpriseApp : enterpriseInstallPolicy.getApps()) {
apps.add(enterpriseApp.getProductId());
}
if (requireSendingToGoogle) {
googleAPIInvoker.approveAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail
.getGoogleUserId(), apps, enterpriseInstallPolicy.getProductSetBehavior());
googleAPIInvoker.updateAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail.getGoogleUserId(),
AndroidEnterpriseUtils.convertToDeviceInstance(enterpriseInstallPolicy));
}
AndroidEnterpriseUtils.getAppSubscriptionService().performEntAppSubscription(uuid,
Arrays.asList(CarbonContext.getThreadLocalCarbonContext().getUsername()),
SubscriptionType.USER.toString(), SubAction.INSTALL.toString(), false);
}
}
} catch (EnterpriseServiceException e) {
String errorMessage = "App install failed for device " + deviceIdentifier.getId();
log.error(errorMessage);
}
}
}

@ -16,7 +16,7 @@
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.common;
package org.wso2.carbon.device.mgt.mobile.android.api.invoker;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
@ -71,8 +71,6 @@ public class GoogleAPIInvoker {
this.esa = esa;
}
private GoogleAPIInvoker(){}
public String insertUser(String enterpriseId, String username) throws EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();

@ -91,17 +91,6 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidenterprise</artifactId>
<version>v1-rev186-1.25.0</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
@ -163,5 +152,15 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidenterprise</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

@ -57,6 +57,9 @@ public final class AndroidPluginConstants {
public static final String OS_BUILD_DATE = "OS_BUILD_DATE";
public static final String MAC_ADDRESS = "MAC";
public static final String GOOGLE_AFW_EMM_ANDROID_ID = "googleEMMAndroidId";
public static final String GOOGLE_AFW_DEVICE_ID = "googleEMMDeviceId";
//Properties related to AD_FEATURE table
public static final String ANDROID_FEATURE_ID = "ID";
public static final String ANDROID_FEATURE_CODE = "CODE";

@ -400,15 +400,14 @@ public interface AndroidService {
/**
* Method for get pending operations
*
* @param id Id of the device to get pending operations
* @param deviceIdentifier Device Identifier of the device to get pending operations
* @param resultOperations Result operations list
* @param disableGoogleApps Check whether google apps are disabled
* @return
* @throws {@link DeviceManagementException}
* @throws {@link InvalidDeviceException}
*/
List<? extends Operation> getPendingOperations
(String id, List<? extends Operation> resultOperations, boolean disableGoogleApps)
(DeviceIdentifier deviceIdentifier, List<? extends Operation> resultOperations)
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException;
/**

@ -18,7 +18,6 @@
package org.wso2.carbon.device.mgt.mobile.android.core.impl;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.services.androidenterprise.model.ProductsListResponse;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.apache.commons.lang.StringUtils;
@ -26,8 +25,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.common.Device;
@ -55,16 +52,13 @@ import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import org.wso2.carbon.device.mgt.mobile.android.common.AndroidConstants;
import org.wso2.carbon.device.mgt.mobile.android.common.GoogleAPIInvoker;
import org.wso2.carbon.device.mgt.mobile.android.common.Message;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.*;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.*;
import org.wso2.carbon.device.mgt.mobile.android.common.dto.AndroidEnterpriseUser;
import org.wso2.carbon.device.mgt.mobile.android.common.exception.*;
import org.wso2.carbon.device.mgt.mobile.android.common.spi.AndroidService;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidAPIUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidDeviceUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidEnterpriseUtils;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
@ -85,8 +79,6 @@ public class AndroidServiceImpl implements AndroidService {
private static final Log log = LogFactory.getLog(AndroidServiceImpl.class);
private static final String OPERATION_ERROR_STATUS = "ERROR";
public static final String GOOGLE_AFW_EMM_ANDROID_ID = "googleEMMAndroidId";
public static final String GOOGLE_AFW_DEVICE_ID = "googleEMMDeviceId";
private static final String EVENT_STREAM_DEFINITION = "org.wso2.iot.LocationStream";
private Gson gson = new Gson();
@ -918,21 +910,20 @@ public class AndroidServiceImpl implements AndroidService {
}
@Override
public List<? extends Operation> getPendingOperations(String deviceId, List<? extends Operation> resultOperations,
boolean disableGoogleApps)
public List<? extends Operation> getPendingOperations(DeviceIdentifier deviceIdentifier,
List<? extends Operation> resultOperations)
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(deviceId);
try {
if (!AndroidDeviceUtils.isValidDeviceIdentifier(deviceIdentifier)) {
String msg = "Device not found for identifier '" + deviceId + "'";
String msg = "Device not found for identifier '" + deviceIdentifier.getId() + "'";
log.error(msg);
throw new InvalidDeviceException(msg);
}
if (log.isDebugEnabled()) {
log.debug("Invoking Android pending operations:" + deviceId);
log.debug("Invoking Android pending operations:" + deviceIdentifier.getId());
}
if (resultOperations != null && !resultOperations.isEmpty()) {
updateOperations(deviceId, resultOperations);
updateOperations(deviceIdentifier.getId(), resultOperations);
}
} catch (OperationManagementException e) {
String msg = "Issue in retrieving operation management service instance";
@ -952,7 +943,7 @@ public class AndroidServiceImpl implements AndroidService {
throw new DeviceManagementException(msg, e);
}
try {
return AndroidDeviceUtils.getPendingOperations(deviceIdentifier, !disableGoogleApps);
return AndroidDeviceUtils.getPendingOperations(deviceIdentifier);
} catch (OperationManagementException e) {
String msg = "Issue in retrieving operation management service instance";
log.error(msg, e);
@ -990,7 +981,6 @@ public class AndroidServiceImpl implements AndroidService {
public Message enrollDevice(AndroidDevice androidDevice)
throws DeviceManagementException, AndroidDeviceMgtPluginException {
try {
String token = null;
Device device = new Device();
device.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
device.setEnrolmentInfo(androidDevice.getEnrolmentInfo());
@ -1002,30 +992,6 @@ public class AndroidServiceImpl implements AndroidService {
device.setFeatures(androidDevice.getFeatures());
device.setProperties(androidDevice.getProperties());
String googleEMMAndroidId = null;
String googleEMMDeviceId = null;
if (androidDevice.getProperties() != null) {
for (Device.Property property : androidDevice.getProperties()) {
if (property.getName().equals(GOOGLE_AFW_EMM_ANDROID_ID)) {
googleEMMAndroidId = property.getValue();
} else if (property.getName().equals(GOOGLE_AFW_DEVICE_ID)) {
googleEMMDeviceId = property.getValue();
}
}
if (googleEMMAndroidId != null && googleEMMDeviceId != null) {
EnterpriseUser user = new EnterpriseUser();
user.setAndroidPlayDeviceId(googleEMMAndroidId);
user.setEmmDeviceIdentifier(googleEMMDeviceId);
try {
token = insertUser(user);
} catch (EnterpriseServiceException e) {
}
}
}
boolean status = AndroidAPIUtils.getDeviceManagementService().enrollDevice(device);
if (status) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(androidDevice.getDeviceIdentifier(),
@ -1082,20 +1048,14 @@ public class AndroidServiceImpl implements AndroidService {
Message responseMessage = new Message();
responseMessage.setResponseCode(String.valueOf(HttpStatusCodes.STATUS_CODE_OK));
if (token == null) {
responseMessage.setResponseMessage("Android device, which carries the id '" +
androidDevice.getDeviceIdentifier() + "' has successfully been enrolled");
} else {
responseMessage.setResponseMessage("Google response token" + token);
}
responseMessage.setResponseMessage("Android device, which carries the id '" +
androidDevice.getDeviceIdentifier() + "' has successfully been enrolled");
return responseMessage;
} else {
Message responseMessage = new Message();
responseMessage.setResponseCode(String.valueOf(HttpStatusCodes.STATUS_CODE_SERVER_ERROR));
responseMessage.setResponseMessage("Failed to enroll '" +
device.getType() + "' device, which carries the id '" +
androidDevice.getDeviceIdentifier() + "'");
return responseMessage;
String msg = "Failed to enroll '" + device.getType() + "' device, which carries the id '" +
androidDevice.getDeviceIdentifier() + "'";
log.error(msg);
throw new DeviceManagementException(msg);
}
} catch (PolicyManagementException | InvalidDeviceException | OperationManagementException e) {
String msg = "Error occurred while enforcing default enrollment policy upon android " +
@ -1392,84 +1352,6 @@ public class AndroidServiceImpl implements AndroidService {
return location;
}
private int recursiveSync(GoogleAPIInvoker googleAPIInvoker, String enterpriseId, ProductsListResponse
productsListResponse) throws EnterpriseServiceException, ApplicationManagementException {
// Are there more pages
if (productsListResponse == null || productsListResponse.getTokenPagination() == null
|| productsListResponse.getTokenPagination().getNextPageToken() == null) {
return 0;
}
// Get next page
ProductsListResponse productsListResponseNext = googleAPIInvoker.listProduct(enterpriseId,
productsListResponse.getTokenPagination().getNextPageToken());
AndroidEnterpriseUtils.persistApp(productsListResponseNext);
if (productsListResponseNext != null && productsListResponseNext.getTokenPagination() != null &&
productsListResponseNext.getTokenPagination().getNextPageToken() != null) {
return recursiveSync(googleAPIInvoker, enterpriseId, productsListResponseNext)
+ productsListResponseNext.getProduct().size();
} else {
return productsListResponseNext.getProduct().size();
}
}
public String insertUser(EnterpriseUser enterpriseUser)
throws EnterpriseServiceException, AndroidDeviceMgtPluginException {
try {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
String token;
boolean deviceIdExist = false;
String googleUserId;
List<AndroidEnterpriseUser> androidEnterpriseUsers = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUser(CarbonContext.getThreadLocalCarbonContext().getUsername());
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
if (androidEnterpriseUsers != null && !androidEnterpriseUsers.isEmpty()) {
googleUserId = androidEnterpriseUsers.get(0).getGoogleUserId();
// If this device is also present, only need to provide a token for this request.
for (AndroidEnterpriseUser enterprise : androidEnterpriseUsers) {
if (enterprise.getEmmDeviceId() != null
&& enterprise.getEmmDeviceId().equals(enterpriseUser.getAndroidPlayDeviceId())) {
deviceIdExist = true;
}
}
} else {
googleUserId = googleAPIInvoker.insertUser(enterpriseConfigs.getEnterpriseId(), CarbonContext
.getThreadLocalCarbonContext()
.getUsername());
}
// Fetching an auth token from Google EMM API
token = googleAPIInvoker.getToken(enterpriseConfigs.getEnterpriseId(), googleUserId);
if (!deviceIdExist) {
AndroidEnterpriseUser androidEnterpriseUser = new AndroidEnterpriseUser();
androidEnterpriseUser.setEmmUsername(CarbonContext.getThreadLocalCarbonContext().getUsername());
androidEnterpriseUser.setTenantId(CarbonContext.getThreadLocalCarbonContext().getTenantId());
androidEnterpriseUser.setAndroidPlayDeviceId(enterpriseUser.getAndroidPlayDeviceId());
androidEnterpriseUser.setEnterpriseId(enterpriseConfigs.getEnterpriseId());
androidEnterpriseUser.setEmmDeviceId(enterpriseUser.getEmmDeviceIdentifier());
androidEnterpriseUser.setGoogleUserId(googleUserId);
AndroidAPIUtils.getAndroidPluginService().addEnterpriseUser(androidEnterpriseUser);
}
return token;
} catch (NotFoundException e) {
String errorMessage = "Not found";
log.error(errorMessage);
throw new NotFoundException(errorMessage);
} catch (UnexpectedServerErrorException e) {
String errorMessage = "Unexpected server error";
log.error(errorMessage);
throw new UnexpectedServerErrorException(errorMessage);
} catch (AndroidDeviceMgtPluginException e) {
String errorMessage = "Error occured while executing wipe enterprice command";
log.error(errorMessage);
throw new AndroidDeviceMgtPluginException(errorMessage);
}
}
private static void validateApplicationUrl(String apkUrl) throws BadRequestException {
try {
URL url = new URL(apkUrl);

@ -60,9 +60,6 @@ import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.application.mgt.common.SubAction;
import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
@ -83,20 +80,13 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
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.operation.mgt.ProfileOperation;
import org.wso2.carbon.device.mgt.core.search.mgt.impl.Utils;
import org.wso2.carbon.device.mgt.mobile.android.common.AndroidConstants;
import org.wso2.carbon.device.mgt.mobile.android.common.GoogleAPIInvoker;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.DeviceState;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.EnterpriseConfigs;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.ErrorListItem;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.ErrorResponse;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.EnterpriseApp;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.EnterpriseInstallPolicy;
import org.wso2.carbon.device.mgt.mobile.android.common.dto.AndroidEnterpriseUser;
import org.wso2.carbon.device.mgt.mobile.android.common.exception.AndroidDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.mobile.android.common.exception.BadRequestException;
import org.wso2.carbon.device.mgt.mobile.android.common.exception.EnterpriseServiceException;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.policy.mgt.common.FeatureManagementException;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
@ -107,7 +97,6 @@ import org.apache.http.impl.client.CloseableHttpClient;
import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -288,110 +277,12 @@ public class AndroidDeviceUtils {
}
public static List<? extends Operation> getPendingOperations
(DeviceIdentifier deviceIdentifier, boolean handleGoogleAps) throws OperationManagementException {
(DeviceIdentifier deviceIdentifier) throws OperationManagementException {
List<? extends Operation> operations;
operations = AndroidAPIUtils.getDeviceManagementService().getPendingOperations(deviceIdentifier);
if (operations != null && handleGoogleAps) {
handleEnrollmentGoogleApps(operations, deviceIdentifier);
}
return operations;
}
private static void handleEnrollmentGoogleApps(List<? extends Operation> operations, DeviceIdentifier
deviceIdentifier) {
boolean containsGoogleAppPolicy = false;
for (int x = 0; x < operations.size() && !containsGoogleAppPolicy; x++) {
Operation operation = operations.get(x);
// Check if the operation has a policy bundle inside.
if (operation.getCode().equals(AndroidConstants.OperationCodes.POLICY_BUNDLE)) {
ArrayList operationPayLoad = (ArrayList) operation.getPayLoad();
// If there is a policy bundle, read its payload
for (int i = 0; i < operationPayLoad.size() && !containsGoogleAppPolicy; i++) {
Object policy = operationPayLoad.get(i);
ProfileOperation profileOperation = (ProfileOperation) policy;
String code = profileOperation.getCode();
// Find if there is an ENROLLMENT_APP_INSTALL payload
if (code.equals(AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_FEATURE_CODE)) {
String payload = profileOperation.getPayLoad().toString();
JsonElement appListElement = new JsonParser().parse(payload).getAsJsonObject()
.get(AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_CODE);
JsonArray appListArray = appListElement.getAsJsonArray();
// Find if there are Apps with Work profile configurations
boolean alreadySendToGoogle = false;
for (JsonElement appElement : appListArray) {
JsonElement googlePolicyPayload = appElement.getAsJsonObject().
get(AndroidConstants.ApplicationInstall.GOOGLE_POLICY_PAYLOAD);
if (googlePolicyPayload != null) {
String uuid = appElement.getAsJsonObject().get("uuid").toString();
containsGoogleAppPolicy = true;// breaking out of outer for loop
try {
uuid = uuid.replace("\"", "");
if (alreadySendToGoogle) {
sendPayloadToGoogle(uuid, payload, deviceIdentifier, false);
} else {
sendPayloadToGoogle(uuid, payload, deviceIdentifier, true);
alreadySendToGoogle = true;
}
} catch (org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException e) {
String errorMessage = "App install failed for device " + deviceIdentifier.getId();
log.error(errorMessage, e);
}
}
}
}
}
}
}
}
/**
* Sends the app install policy to Google
* @param payload policy profile
* @param deviceIdentifier device to apply policy
*/
private static void sendPayloadToGoogle(String uuid, String payload, DeviceIdentifier deviceIdentifier,
boolean requireSendingToGoogle) throws ApplicationManagementException {
try {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigsFromGoogle();
if (enterpriseConfigs.getErrorResponse() == null) {
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
AndroidEnterpriseUser userDetail = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUserByDevice(deviceIdentifier.getId());
if (userDetail != null && userDetail.getEnterpriseId() != null && !userDetail.getEnterpriseId()
.isEmpty() && userDetail.getEmmUsername() != null && payload != null) {
EnterpriseInstallPolicy enterpriseInstallPolicy = AndroidEnterpriseUtils
.getDeviceAppPolicy(payload, null, userDetail);
List<String> apps = new ArrayList<>();
for (EnterpriseApp enterpriseApp : enterpriseInstallPolicy.getApps()) {
apps.add(enterpriseApp.getProductId());
}
if (requireSendingToGoogle) {
googleAPIInvoker.approveAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail
.getGoogleUserId(), apps, enterpriseInstallPolicy.getProductSetBehavior());
googleAPIInvoker.updateAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail.getGoogleUserId(),
AndroidEnterpriseUtils.convertToDeviceInstance(enterpriseInstallPolicy));
}
AndroidEnterpriseUtils.getAppSubscriptionService().performEntAppSubscription(uuid,
Arrays.asList(CarbonContext.getThreadLocalCarbonContext().getUsername()),
SubscriptionType.USER.toString(), SubAction.INSTALL.toString(), false);
}
}
} catch (EnterpriseServiceException e) {
String errorMessage = "App install failed for device " + deviceIdentifier.getId();
log.error(errorMessage);
}
}
private static void updateApplicationList(Operation operation, DeviceIdentifier deviceIdentifier)
throws org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException {
// Parsing json string to get applications list.
@ -748,7 +639,7 @@ public class AndroidDeviceUtils {
public static void updateDisEnrollOperationStatus(DeviceIdentifier deviceIdentifier)
throws DeviceManagementException {
try {
List<? extends Operation> pendingOperations = getPendingOperations(deviceIdentifier, false);
List<? extends Operation> pendingOperations = getPendingOperations(deviceIdentifier);
if (pendingOperations != null && !pendingOperations.isEmpty()) {
for (Operation operation : pendingOperations) {
operation.setStatus(Operation.Status.ERROR);

@ -29,11 +29,11 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
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.mobile.android.common.Message;
import org.wso2.carbon.device.mgt.mobile.android.common.bean.wrapper.AndroidDevice;
import org.wso2.carbon.device.mgt.mobile.android.common.exception.AndroidDeviceMgtPluginException;
@ -45,6 +45,7 @@ import org.wso2.carbon.device.mgt.mobile.android.core.mokcs.NotificationManageme
import org.wso2.carbon.device.mgt.mobile.android.core.mokcs.PolicyManagerServiceMock;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidAPIUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.mokcs.utils.TestUtils;
import org.wso2.carbon.device.mgt.mobile.android.core.util.AndroidDeviceUtils;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
@ -111,7 +112,7 @@ public class DeviceManagementServiceTests {
public void testGetPendingOperationsForNullDevice()
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
List<? extends Operation> resultOperations = new ArrayList<>();
androidService.getPendingOperations(null, resultOperations, true);
androidService.getPendingOperations(null, resultOperations);
}
@Test (expectedExceptions = {InvalidDeviceException.class})
@ -119,15 +120,17 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
List<? extends Operation> resultOperations = new ArrayList<>();
androidService.getPendingOperations("1234", resultOperations, true);
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject("1234");
androidService.getPendingOperations(deviceIdentifier, resultOperations);
}
@Test
public void testGetPendingOperationsNullResponse()
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(TestUtils.getDeviceId());
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(TestUtils.getDeviceId(), null, true);
.getPendingOperations(deviceIdentifier, null);
Assert.assertNotNull(pendingOperations);
Assert.assertFalse((pendingOperations.isEmpty()));
}
@ -137,8 +140,9 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
mockPolicyManagerService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(TestUtils.getDeviceId());
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(TestUtils.getDeviceId(), TestUtils.getSuccessMonitorOperationResponse(), true);
.getPendingOperations(deviceIdentifier, TestUtils.getSuccessMonitorOperationResponse());
Assert.assertNotNull(pendingOperations);
Assert.assertFalse((pendingOperations.isEmpty()));
}
@ -148,9 +152,9 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
mockApplicationManagerService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(TestUtils.getDeviceId());
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(TestUtils.getDeviceId(), TestUtils.getSuccessApplicationOperationResponse(),
true);
.getPendingOperations(deviceIdentifier, TestUtils.getSuccessApplicationOperationResponse());
Assert.assertNotNull(pendingOperations);
Assert.assertFalse((pendingOperations.isEmpty()));
}
@ -160,20 +164,20 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
mockDeviceInformationManagerService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(TestUtils.getDeviceId());
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(TestUtils.getDeviceId(),
TestUtils.getSuccessInfoOperationResponse(), true);
.getPendingOperations(deviceIdentifier, TestUtils.getSuccessInfoOperationResponse());
Assert.assertNotNull(pendingOperations);
Assert.assertFalse((pendingOperations.isEmpty()));
}
@Test
public void testGetPendingOperationsWithInProgressResponse()
throws DeviceManagementException, OperationManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(TestUtils.getDeviceId());
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(TestUtils.getDeviceId(),
TestUtils.getInProgressOperationResponse(), true);
.getPendingOperations(deviceIdentifier, TestUtils.getInProgressOperationResponse());
Assert.assertNotNull(pendingOperations);
Assert.assertFalse((pendingOperations.isEmpty()));
}
@ -183,9 +187,9 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, InvalidDeviceException, AndroidDeviceMgtPluginException {
mockDeviceManagementService();
mockNotificationManagementService();
DeviceIdentifier deviceIdentifier = AndroidDeviceUtils.convertToDeviceIdentifierObject(TestUtils.getDeviceId());
List<? extends Operation> pendingOperations = androidService
.getPendingOperations(TestUtils.getDeviceId(),
TestUtils.getErrorOperationResponse(), true);
.getPendingOperations(deviceIdentifier, TestUtils.getErrorOperationResponse());
Assert.assertNotNull(pendingOperations);
Assert.assertFalse((pendingOperations.isEmpty()));
}

@ -661,6 +661,18 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
return null;
}
@Override public boolean deleteDeviceTypeVersions(DeviceType deviceType) throws DeviceManagementException {
return false;
}
@Override public void disEnrollDevices(List<Device> list) throws DeviceManagementException {
}
@Override public boolean deleteDeviceType(String s, DeviceType deviceType) throws DeviceManagementException {
return false;
}
@Override
public DeviceConfiguration getDeviceConfiguration(Map<String, String> propertyMap)
throws DeviceManagementException, DeviceNotFoundException, UnauthorizedDeviceAccessException,

@ -1154,6 +1154,11 @@
<type>apk</type>
<version>${android.agent.version}</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidenterprise</artifactId>
<version>v1-rev214-1.25.0</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save