Add APIs for Google Enterprise

revert-dabc3590
Dharmakeerthi Lasantha 5 years ago
commit 8ff1eb4751

@ -359,6 +359,11 @@
<artifactId>org.wso2.carbon.apimgt.application.extension</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidenterprise</artifactId>
<version>v1-rev186-1.25.0</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.application.mgt.common</artifactId>

@ -0,0 +1,87 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.mdm.services.android.bean;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "BasicUserInfo", description = "Basic user information and the roles of the user.")
public class BasicUserInfo {
@ApiModelProperty(name = "username", value = "The login name of the user.", required = true )
private String username;
@ApiModelProperty(name = "firstname", value = "The first name of the user.", required = true )
private String firstname;
@ApiModelProperty(name = "lastname", value = "The last name of the user.", required = true )
private String lastname;
@ApiModelProperty(name = "emailAddress", value = "The email address of the user.", required = true )
private String emailAddress;
@ApiModelProperty(name = "createdDate", value = "User creation date." )
private String createdDate;
@ApiModelProperty(name = "modifiedDate", value = "User modifiedDate date." )
private String modifiedDate;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
}

@ -0,0 +1,32 @@
package org.wso2.carbon.mdm.services.android.bean;
public class EnterpriseConfigs {
String enterpriseId;
String esa;
ErrorResponse errorResponse;
public ErrorResponse getErrorResponse() {
return errorResponse;
}
public void setErrorResponse(ErrorResponse errorResponse) {
this.errorResponse = errorResponse;
}
public String getEnterpriseId() {
return enterpriseId;
}
public void setEnterpriseId(String enterpriseId) {
this.enterpriseId = enterpriseId;
}
public String getEsa() {
return esa;
}
public void setEsa(String esa) {
this.esa = esa;
}
}

@ -0,0 +1,72 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean;
import java.util.List;
public class EnterpriseStoreCluster {
String pageId;
String clusterId;
String name;
List<EnterpriseStorePackages> products;
String orderInPage;
public String getClusterId() {
return clusterId;
}
public void setClusterId(String clusterId) {
this.clusterId = clusterId;
}
public String getPageId() {
return pageId;
}
public void setPageId(String pageId) {
this.pageId = pageId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<EnterpriseStorePackages> getProducts() {
return products;
}
public void setProducts(List<EnterpriseStorePackages> products) {
this.products = products;
}
public String getOrderInPage() {
return orderInPage;
}
public void setOrderInPage(String orderInPage) {
this.orderInPage = orderInPage;
}
}

@ -0,0 +1,43 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean;
public class EnterpriseStorePackages {
String packageId;
String iconUrl;
public String getPackageId() {
return packageId;
}
public void setPackageId(String packageId) {
this.packageId = packageId;
}
public String getIconUrl() {
return iconUrl;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
}

@ -0,0 +1,61 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean;
import java.util.List;
public class EnterpriseStorePage {
String locale;
String pageName;
String pageId;
List<String> links;
public String getPageId() {
return pageId;
}
public void setPageId(String pageId) {
this.pageId = pageId;
}
public List<String> getLinks() {
return links;
}
public void setLinks(List<String> links) {
this.links = links;
}
public String getLocale() {
return locale;
}
public void setLocale(String locale) {
this.locale = locale;
}
public String getPageName() {
return pageName;
}
public void setPageName(String pageName) {
this.pageName = pageName;
}
}

@ -0,0 +1,44 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean;
import java.util.List;
public class EnterpriseStorePageLinks {
String pageId;
List<String> links;
public String getPageId() {
return pageId;
}
public void setPageId(String pageId) {
this.pageId = pageId;
}
public List<String> getLinks() {
return links;
}
public void setLinks(List<String> links) {
this.links = links;
}
}

@ -0,0 +1,96 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean;
public class EnterpriseTokenUrl {
String enterpriseId;
String parentHost;
boolean approveApps;
boolean searchEnabled;
boolean isPrivateAppsEnabled;
boolean isWebAppEnabled;
boolean isOrganizeAppPageVisible;
boolean isManagedConfigEnabled;
public String getEnterpriseId() {
return enterpriseId;
}
public void setEnterpriseId(String enterpriseId) {
this.enterpriseId = enterpriseId;
}
public String getParentHost() {
return parentHost;
}
public void setParentHost(String parentHost) {
this.parentHost = parentHost;
}
public boolean isApproveApps() {
return approveApps;
}
public void setApproveApps(boolean approveApps) {
this.approveApps = approveApps;
}
public boolean isSearchEnabled() {
return searchEnabled;
}
public void setSearchEnabled(boolean searchEnabled) {
this.searchEnabled = searchEnabled;
}
public boolean isPrivateAppsEnabled() {
return isPrivateAppsEnabled;
}
public void setPrivateAppsEnabled(boolean privateAppsEnabled) {
isPrivateAppsEnabled = privateAppsEnabled;
}
public boolean isWebAppEnabled() {
return isWebAppEnabled;
}
public void setWebAppEnabled(boolean webAppEnabled) {
isWebAppEnabled = webAppEnabled;
}
public boolean isOrganizeAppPageVisible() {
return isOrganizeAppPageVisible;
}
public void setOrganizeAppPageVisible(boolean organizeAppPageVisible) {
isOrganizeAppPageVisible = organizeAppPageVisible;
}
public boolean isManagedConfigEnabled() {
return isManagedConfigEnabled;
}
public void setManagedConfigEnabled(boolean managedConfigEnabled) {
isManagedConfigEnabled = managedConfigEnabled;
}
}

@ -0,0 +1,14 @@
package org.wso2.carbon.mdm.services.android.bean;
public class GoogleAppSyncResponse {
int totalApps;
public int getTotalApps() {
return totalApps;
}
public void setTotalApps(int totalApps) {
this.totalApps = totalApps;
}
}

@ -0,0 +1,102 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean.wrapper;
import com.google.api.services.androidenterprise.model.VariableSet;
import java.io.Serializable;
import java.util.List;
public class EnterpriseApp implements Serializable {
private static final long serialVersionUID = 45598101734L;
String productId;
String autoInstallMode;
int autoInstallPriority;
String chargingStateConstraint;
String deviceIdleStateConstraint;
String networkTypeConstraint;
String mcmId;
List<VariableSet> variableSet;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getAutoInstallMode() {
return autoInstallMode;
}
public void setAutoInstallMode(String autoInstallMode) {
this.autoInstallMode = autoInstallMode;
}
public int getAutoInstallPriority() {
return autoInstallPriority;
}
public void setAutoInstallPriority(int autoInstallPriority) {
this.autoInstallPriority = autoInstallPriority;
}
public String getChargingStateConstraint() {
return chargingStateConstraint;
}
public void setChargingStateConstraint(String chargingStateConstraint) {
this.chargingStateConstraint = chargingStateConstraint;
}
public String getDeviceIdleStateConstraint() {
return deviceIdleStateConstraint;
}
public void setDeviceIdleStateConstraint(String deviceIdleStateConstraint) {
this.deviceIdleStateConstraint = deviceIdleStateConstraint;
}
public String getNetworkTypeConstraint() {
return networkTypeConstraint;
}
public void setNetworkTypeConstraint(String networkTypeConstraint) {
this.networkTypeConstraint = networkTypeConstraint;
}
public String getMcmId() {
return mcmId;
}
public void setMcmId(String mcmId) {
this.mcmId = mcmId;
}
public List<VariableSet> getVariableSet() {
return variableSet;
}
public void setVariableSet(List<VariableSet> variableSet) {
this.variableSet = variableSet;
}
}

@ -0,0 +1,100 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean.wrapper;
import java.io.Serializable;
import java.util.List;
public class EnterpriseInstallPolicy implements Serializable {
private static final long serialVersionUID = 15598101712L;
String username;
String managementType;
String kind;
String androidId;
String autoUpdatePolicy;
String productAvailabilityPolicy;
String productSetBehavior;
List<EnterpriseApp> apps;
public String getProductSetBehavior() {
return productSetBehavior;
}
public void setProductSetBehavior(String productSetBehavior) {
this.productSetBehavior = productSetBehavior;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getManagementType() {
return managementType;
}
public void setManagementType(String managementType) {
this.managementType = managementType;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getAndroidId() {
return androidId;
}
public void setAndroidId(String androidId) {
this.androidId = androidId;
}
public String getAutoUpdatePolicy() {
return autoUpdatePolicy;
}
public void setAutoUpdatePolicy(String autoUpdatePolicy) {
this.autoUpdatePolicy = autoUpdatePolicy;
}
public String getProductAvailabilityPolicy() {
return productAvailabilityPolicy;
}
public void setProductAvailabilityPolicy(String productAvailabilityPolicy) {
this.productAvailabilityPolicy = productAvailabilityPolicy;
}
public List<EnterpriseApp> getApps() {
return apps;
}
public void setApps(List<EnterpriseApp> apps) {
this.apps = apps;
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.bean.wrapper;
public class EnterpriseUser {
String token;
String emmDeviceIdentifier;
String androidPlayDeviceId;
public String getEmmDeviceIdentifier() {
return emmDeviceIdentifier;
}
public void setEmmDeviceIdentifier(String emmDeviceIdentifier) {
this.emmDeviceIdentifier = emmDeviceIdentifier;
}
public String getAndroidPlayDeviceId() {
return androidPlayDeviceId;
}
public void setAndroidPlayDeviceId(String androidPlayDeviceId) {
this.androidPlayDeviceId = androidPlayDeviceId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}

@ -0,0 +1,14 @@
package org.wso2.carbon.mdm.services.android.bean.wrapper;
public class TokenWrapper {
String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}

@ -0,0 +1,357 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.mdm.services.android.common;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.androidenterprise.AndroidEnterprise;
import com.google.api.services.androidenterprise.AndroidEnterpriseScopes;
import com.google.api.services.androidenterprise.model.AdministratorWebToken;
import com.google.api.services.androidenterprise.model.AdministratorWebTokenSpec;
import com.google.api.services.androidenterprise.model.AdministratorWebTokenSpecManagedConfigurations;
import com.google.api.services.androidenterprise.model.AdministratorWebTokenSpecPlaySearch;
import com.google.api.services.androidenterprise.model.AdministratorWebTokenSpecPrivateApps;
import com.google.api.services.androidenterprise.model.AdministratorWebTokenSpecStoreBuilder;
import com.google.api.services.androidenterprise.model.AdministratorWebTokenSpecWebApps;
import com.google.api.services.androidenterprise.model.AuthenticationToken;
import com.google.api.services.androidenterprise.model.Device;
import com.google.api.services.androidenterprise.model.Install;
import com.google.api.services.androidenterprise.model.LocalizedText;
import com.google.api.services.androidenterprise.model.ProductSet;
import com.google.api.services.androidenterprise.model.ProductsListResponse;
import com.google.api.services.androidenterprise.model.StoreCluster;
import com.google.api.services.androidenterprise.model.StoreLayout;
import com.google.api.services.androidenterprise.model.StoreLayoutClustersListResponse;
import com.google.api.services.androidenterprise.model.StoreLayoutPagesListResponse;
import com.google.api.services.androidenterprise.model.StorePage;
import com.google.api.services.androidenterprise.model.User;
import com.google.common.collect.ImmutableList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.EnterpriseServiceException;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStoreCluster;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStorePackages;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStorePage;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseTokenUrl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class GoogleAPIInvoker {
private static final Log log = LogFactory.getLog(GoogleAPIInvoker.class);
private String esa;
public GoogleAPIInvoker(String esa) {
this.esa = esa;
}
private GoogleAPIInvoker(){}
public String insertUser(String enterpriseId, String username) throws EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
User user = new User();
user.setAccountIdentifier(username);
user.setDisplayName(username);
user.setAccountType("userAccount");
user.setManagementType("emmManaged");
try {
User addedUser = androidEnterprise.users().insert(enterpriseId, user)
.execute();
return addedUser.getId();
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public String getToken(String enterpriseId, String userId) throws EnterpriseServiceException{
AndroidEnterprise androidEnterprise = getEnterpriseClient();
try {
AuthenticationToken tokenResponse = androidEnterprise.users()
.generateAuthenticationToken(enterpriseId, userId).execute();
return tokenResponse.getToken();
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs getToken";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public Device updateAppsForUser(String enterpriseId, String userId , Device device) throws
EnterpriseServiceException{
AndroidEnterprise androidEnterprise = getEnterpriseClient();
try {
Device deviceResponse = androidEnterprise.devices().update(enterpriseId,
userId, device.getAndroidId(), device)
.execute();
return deviceResponse;
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs installApps";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public Install installApps(String enterpriseId, String userId , String deviceId, String productId) throws
EnterpriseServiceException{
AndroidEnterprise androidEnterprise = getEnterpriseClient();
try {
Install install = new Install();
install.setKind("androidenterprise#install");
install.setProductId(productId);
return androidEnterprise.installs().update(enterpriseId, userId, deviceId, productId, install).execute();
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs installApps";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public void uninstallApps(String enterpriseId, String userId , String deviceId, String productId) throws
EnterpriseServiceException{
AndroidEnterprise androidEnterprise = getEnterpriseClient();
try {
androidEnterprise.installs().delete(enterpriseId, userId, deviceId, productId).execute();
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs installApps";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public void approveAppsForUser(String enterpriseId, String userId , List<String> products, String approvalType)
throws EnterpriseServiceException{
AndroidEnterprise androidEnterprise = getEnterpriseClient();
try {
ProductSet productSet = new ProductSet();
productSet.setKind("androidenterprise#productSet");
productSet.setProductId(products);
productSet.setProductSetBehavior(approvalType);
androidEnterprise.users().setAvailableProductSet(enterpriseId, userId, productSet).execute();
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs approveAppsForUser";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public String getAdministratorWebToken(EnterpriseTokenUrl enterpriseTokenUrl) throws EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
AdministratorWebTokenSpec tokenSpec = new AdministratorWebTokenSpec();
tokenSpec.setParent(enterpriseTokenUrl.getParentHost());
tokenSpec.setPlaySearch(new AdministratorWebTokenSpecPlaySearch()
.setApproveApps(enterpriseTokenUrl.isApproveApps())
.setEnabled(enterpriseTokenUrl.isSearchEnabled()));
tokenSpec.setPrivateApps(new AdministratorWebTokenSpecPrivateApps()
.setEnabled(enterpriseTokenUrl.isPrivateAppsEnabled()));
tokenSpec.setWebApps(new AdministratorWebTokenSpecWebApps().setEnabled(enterpriseTokenUrl.isWebAppEnabled()));
tokenSpec.setStoreBuilder(new AdministratorWebTokenSpecStoreBuilder()
.setEnabled(enterpriseTokenUrl.isOrganizeAppPageVisible()));
tokenSpec.setManagedConfigurations(new AdministratorWebTokenSpecManagedConfigurations()
.setEnabled(enterpriseTokenUrl.isManagedConfigEnabled()));
try {
AdministratorWebToken token = androidEnterprise.enterprises()
.createWebToken(enterpriseTokenUrl.getEnterpriseId(), tokenSpec).execute();
return token.getToken();
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs installApps";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public ProductsListResponse listProduct(String enterpriseId, String token) throws EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
try {
if (token == null) {
return androidEnterprise.products().list(enterpriseId).setMaxResults(100l).setApproved(true).execute();
} else {
return androidEnterprise.products().list(enterpriseId).setMaxResults(100l).setToken(token)
.setApproved(true).execute();
}
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs installApps";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
}
public String insertPage(String enterpriseId, EnterpriseStorePage storePage) throws IOException,
EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
List<LocalizedText> names =
ImmutableList.of(new LocalizedText().setLocale(storePage.getLocale()).setText(storePage.getPageName()));
StorePage page = new StorePage();
page.setName(names);
return androidEnterprise.storelayoutpages().insert(enterpriseId, page).execute().getId();
}
public String updatePage(String enterpriseId, EnterpriseStorePage storePage) throws IOException,
EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
List<LocalizedText> names =
ImmutableList.of(new LocalizedText().setLocale(storePage.getLocale()).setText(storePage.getPageName()));
StorePage page = new StorePage();
page.setName(names);
page.setLink(storePage.getLinks());
return androidEnterprise.storelayoutpages().update(enterpriseId, storePage.getPageId(), page).execute().getId();
}
public void deletePage(String enterpriseId, String pageId) throws IOException,
EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
androidEnterprise.storelayoutpages().delete(enterpriseId, pageId).execute();
}
public StoreLayoutPagesListResponse listPages(String enterpriseId) throws IOException,
EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
return androidEnterprise.storelayoutpages().list(enterpriseId).execute();
}
public StoreLayout setStoreLayout(String enterpriseId, String homepageId)
throws EnterpriseServiceException, IOException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
StoreLayout storeLayout = new StoreLayout();
storeLayout.setStoreLayoutType("custom");
storeLayout.setHomepageId(homepageId);
return androidEnterprise
.enterprises()
.setStoreLayout(enterpriseId, storeLayout)
.execute();
}
public String insertCluster(String enterpriseId, EnterpriseStoreCluster storeCluster) throws IOException ,
EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
StoreCluster cluster = new StoreCluster();
List<LocalizedText> names =
ImmutableList.of(new LocalizedText().setLocale("en").setText(storeCluster.getName()));
cluster.setName(names);
List<String> productIds = new ArrayList<>();
for (EnterpriseStorePackages packages : storeCluster.getProducts()) {
productIds.add(packages.getPackageId());
}
cluster.setProductId(productIds);
cluster.setOrderInPage(storeCluster.getOrderInPage());
return androidEnterprise.storelayoutclusters()
.insert(enterpriseId, storeCluster.getPageId(), cluster)
.execute()
.getId();
}
public String updateCluster(String enterpriseId, EnterpriseStoreCluster storeCluster) throws IOException ,
EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
StoreCluster cluster = new StoreCluster();
List<LocalizedText> names =
ImmutableList.of(new LocalizedText().setLocale("en").setText(storeCluster.getName()));
cluster.setName(names);
List<String> productIds = new ArrayList<>();
for (EnterpriseStorePackages packages : storeCluster.getProducts()) {
productIds.add(packages.getPackageId());
}
cluster.setProductId(productIds);
cluster.setOrderInPage(storeCluster.getOrderInPage());
cluster.setId(storeCluster.getClusterId());
return androidEnterprise.storelayoutclusters()
.update(enterpriseId, storeCluster.getPageId(), storeCluster.getClusterId(), cluster)
.execute()
.getId();
}
public StoreLayoutClustersListResponse getClusters(String enterpriseId, String pageId)
throws IOException, EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
return androidEnterprise.storelayoutclusters().list(enterpriseId, pageId).execute();
}
public void deleteCluster(String enterpriseId, String pageId, String clusterId)
throws IOException, EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
androidEnterprise.storelayoutclusters().delete(enterpriseId, pageId, clusterId).execute();
}
// Update the pages to include quick links to other pages.
public void addLinks(String enterpriseId, String pageId, List<String> links)
throws IOException , EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
androidEnterprise.storelayoutpages()
.patch(enterpriseId, pageId, new StorePage().setLink(links)).execute();
}
public StoreLayout getStoreLayout(String enterpriseId)
throws IOException, EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
return androidEnterprise
.enterprises()
.getStoreLayout(enterpriseId)
.execute();
}
public void unenroll(String enterpriseId)
throws IOException, EnterpriseServiceException {
AndroidEnterprise androidEnterprise = getEnterpriseClient();
// androidEnterprise.enterprises().unenroll(enterpriseId).execute();
}
private AndroidEnterprise getEnterpriseClient() throws EnterpriseServiceException {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
InputStream inputStream = new ByteArrayInputStream(esa.getBytes(StandardCharsets.UTF_8));
final Credential credential;
try {
credential = GoogleCredential.fromStream(inputStream, httpTransport, jsonFactory)
.createScoped(AndroidEnterpriseScopes.all());
} catch (IOException e) {
String msg = "Error occurred while accessing Google APIs";
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
}
HttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest request) throws IOException {
credential.initialize(request);
}
};
return new AndroidEnterprise.Builder(httpTransport, jsonFactory, httpRequestInitializer)
.build();
}
}

@ -209,6 +209,11 @@ public interface DeviceManagementService {
message = "Internal Server Error. \n Server error occurred while fetching the list of pending operations.")
})
Response getPendingOperations(
@ApiParam(
name = "disableGoogleApps",
value = "Specifically disable having Google apps installed.",
required = false)
@QueryParam("disableGoogleApps") boolean disableGoogleApps,
@ApiParam(
name = "id",
value = "The unique device identifier.",

@ -0,0 +1,814 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.mdm.services.android.services.impl;
import com.google.api.services.androidenterprise.model.AppRestrictionsSchema;
import com.google.api.services.androidenterprise.model.ProductsListResponse;
import com.google.api.services.androidenterprise.model.StoreCluster;
import com.google.api.services.androidenterprise.model.StoreLayout;
import com.google.api.services.androidenterprise.model.StoreLayoutClustersListResponse;
import com.google.api.services.androidenterprise.model.StoreLayoutPagesListResponse;
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.dto.ApplicationPolicyDTO;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
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.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
import org.wso2.carbon.device.mgt.mobile.android.impl.EnterpriseServiceException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseManagedConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseConfigs;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStoreCluster;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStorePackages;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStorePage;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseStorePageLinks;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseTokenUrl;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.GoogleAppSyncResponse;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseApp;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseInstallPolicy;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseUser;
import org.wso2.carbon.mdm.services.android.bean.wrapper.TokenWrapper;
import org.wso2.carbon.mdm.services.android.common.GoogleAPIInvoker;
import org.wso2.carbon.mdm.services.android.exception.BadRequestException;
import org.wso2.carbon.mdm.services.android.exception.NotFoundException;
import org.wso2.carbon.mdm.services.android.services.AndroidEnterpriseService;
import org.wso2.carbon.mdm.services.android.util.AndroidAPIUtils;
import org.wso2.carbon.mdm.services.android.util.AndroidConstants;
import org.wso2.carbon.mdm.services.android.util.AndroidDeviceUtils;
import org.wso2.carbon.mdm.services.android.util.AndroidEnterpriseUtils;
import org.wso2.carbon.policy.mgt.common.FeatureManagementException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Path("/enterprise")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class AndroidEnterpriseServiceImpl implements AndroidEnterpriseService {
private static final Log log = LogFactory.getLog(AndroidEnterpriseServiceImpl.class);
@Override
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@POST
@Path("/user")
public Response addUser(EnterpriseUser enterpriseUser) {
if (enterpriseUser == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
} else if (enterpriseUser.getEmmDeviceIdentifier() == null || enterpriseUser.getEmmDeviceIdentifier().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("EMM ID is incorrect").build())
.build();
} else if (enterpriseUser.getAndroidPlayDeviceId() == null || enterpriseUser.getAndroidPlayDeviceId().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Google Play ID is incorrect").build())
.build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
String token;
boolean deviceIdExist = false;
try {
String googleUserId;
List<AndroidEnterpriseUser> androidEnterpriseUsers = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUser(CarbonContext.getThreadLocalCarbonContext().getUsername());
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
if (androidEnterpriseUsers != null && androidEnterpriseUsers.size() > 0) {
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);
}
if (token == null) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching token").build())
.build();
}
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when saving user").build()).build();
}
return Response.status(Response.Status.OK).entity(token).build();
}
@Override
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@POST
@Path("/available-app")
public Response updateUser(EnterpriseInstallPolicy device) {
boolean sentToDevice = false;
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
try {
List<AndroidEnterpriseUser> enterpriseUserInstances = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUser(device.getUsername());
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
for (AndroidEnterpriseUser userDetail : enterpriseUserInstances) {
if (userDetail.getEnterpriseId() != null && !userDetail.getEnterpriseId().isEmpty() && userDetail
.getEmmUsername() != null && userDetail.getEmmUsername().equals(device.getUsername())
&& device.getAndroidId().equals(userDetail.getAndroidPlayDeviceId())) {
googleAPIInvoker.updateAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail.getGoogleUserId(),
AndroidEnterpriseUtils.convertToDeviceInstance(device));
sentToDevice = true;
}
}
} catch (EnterpriseServiceException e) {
String errorMessage = "App install failed. No user found for name " + device.getUsername();
log.error(errorMessage);
throw new NotFoundException(
new ErrorResponse.ErrorResponseBuilder().setCode(404l).setMessage(errorMessage).build());
}
if (sentToDevice) {
return Response.status(Response.Status.OK).build();
} else {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Could not install on the device of user "
+ device.getUsername()).build()).build();
}
}
@Override
@GET
@Path("/store-url")
public Response getStoreUrl(@QueryParam("approveApps") boolean approveApps,
@QueryParam("searchEnabled") boolean searchEnabled,
@QueryParam("isPrivateAppsEnabled") boolean isPrivateAppsEnabled,
@QueryParam("isWebAppEnabled") boolean isWebAppEnabled,
@QueryParam("isOrganizeAppPageVisible") boolean isOrganizeAppPageVisible,
@QueryParam("isManagedConfigEnabled") boolean isManagedConfigEnabled,
@QueryParam("host") String host) {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
EnterpriseTokenUrl enterpriseTokenUrl = new EnterpriseTokenUrl();
if (enterpriseConfigs == null || enterpriseConfigs.getEnterpriseId() == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Not configured for AFW").build()).build();
}
enterpriseTokenUrl.setEnterpriseId(enterpriseConfigs.getEnterpriseId());
enterpriseTokenUrl.setApproveApps(approveApps);
enterpriseTokenUrl.setSearchEnabled(searchEnabled);
enterpriseTokenUrl.setPrivateAppsEnabled(isPrivateAppsEnabled);
enterpriseTokenUrl.setWebAppEnabled(isWebAppEnabled);
enterpriseTokenUrl.setOrganizeAppPageVisible(isOrganizeAppPageVisible);
enterpriseTokenUrl.setParentHost(host);
enterpriseTokenUrl.setManagedConfigEnabled(isManagedConfigEnabled);
try {
String token = googleAPIInvoker.getAdministratorWebToken(enterpriseTokenUrl);
TokenWrapper tokenWrapper = new TokenWrapper();
tokenWrapper.setToken(token);
return Response.status(Response.Status.OK).entity(tokenWrapper).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when calling get web token").build())
.build();
}
}
@Override
@GET
@Path("/products/sync")
public Response syncApps() {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
ProductsListResponse productsListResponse = googleAPIInvoker
.listProduct(enterpriseConfigs.getEnterpriseId(), null);
AndroidEnterpriseUtils.persistApp(productsListResponse);
int total = productsListResponse.getProduct().size()
+ recursiveSync(googleAPIInvoker, enterpriseConfigs.getEnterpriseId(), productsListResponse);
GoogleAppSyncResponse appSyncResponse = new GoogleAppSyncResponse();
appSyncResponse.setTotalApps(total);
return Response.status(Response.Status.OK).entity(appSyncResponse).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when calling sync").build())
.build();
} catch (ApplicationManagementException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when persisting app").build())
.build();
}
}
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();
}
}
@POST
@Path("/store-layout/page")
@Override
public Response addPage(EnterpriseStorePage page) {
if (page == null || page.getPageName() == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
String id = googleAPIInvoker.insertPage(enterpriseConfigs.getEnterpriseId(), page);
page.setPageId(id);
return Response.status(Response.Status.OK).entity(page).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when inserting page "
+ page.getPageName()).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when inserting page "
+ page.getPageName() + " , due to an error with ESA").build() ).build();
}
}
@PUT
@Path("/store-layout/page")
@Override
public Response updatePage(EnterpriseStorePage page) {
if (page == null || page.getPageName() == null || page.getPageId() == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
String id = googleAPIInvoker.updatePage(enterpriseConfigs.getEnterpriseId(), page);
page.setPageId(id);
return Response.status(Response.Status.OK).entity(page).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating page "
+ page.getPageName()).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating page "
+ page.getPageName() + " , due to an error with ESA").build()).build();
}
}
@DELETE
@Path("/store-layout/page/{id}")
@Override
public Response deletePage(@PathParam("id") String id) {
if (id == null || id.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Page Id cannot be empty").build())
.build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
googleAPIInvoker.deletePage(enterpriseConfigs.getEnterpriseId(), id);
return Response.status(Response.Status.OK).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when deleting page "
+ id).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating page "
+ id + " , Due to an error with ESA").build()).build();
}
}
@GET
@Path("/store-layout/page")
@Override
public Response getPages() {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
StoreLayoutPagesListResponse pages = googleAPIInvoker.listPages(enterpriseConfigs.getEnterpriseId());
return Response.status(Response.Status.OK).entity(pages).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching all pages").build())
.build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching page "
+ " , Due to an error with ESA").build()).build();
}
}
@PUT
@Path("/store-layout/home-page/{id}")
@Override
public Response setHome(@PathParam("id") String id) {
if (id == null || id.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Id cannot be empty").build())
.build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
StoreLayout layout = googleAPIInvoker.setStoreLayout(enterpriseConfigs.getEnterpriseId(), id);
return Response.status(Response.Status.OK).entity(layout).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when inserting home page "
+ id).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when inserting home page "
+ id + " , due to an error with ESA").build() ).build();
}
}
@GET
@Path("/store-layout/home-page")
@Override
public Response getHome() {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
StoreLayout layout = googleAPIInvoker.getStoreLayout(enterpriseConfigs.getEnterpriseId());
return Response.status(Response.Status.OK).entity(layout).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching home page").build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching home page.").build() )
.build();
}
}
@POST
@Path("/store-layout/cluster")
@Override
public Response addCluster(EnterpriseStoreCluster storeCluster) {
if (storeCluster == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
} else if (storeCluster.getName() == null || storeCluster.getName().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Cluster name cannot be empty").build()).build();
} else if (storeCluster.getProducts() == null || storeCluster.getProducts().size() < 0) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Products cannot be empty").build()).build();
} else if (storeCluster.getOrderInPage() == null || storeCluster.getOrderInPage().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Cluster order cannot be empty").build()).build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
String id = googleAPIInvoker.insertCluster(enterpriseConfigs.getEnterpriseId(), storeCluster);
storeCluster.setClusterId(id);
return Response.status(Response.Status.OK).entity(storeCluster).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating cluster "
+ storeCluster.getName()).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating cluster "
+ storeCluster.getName() + " , due to an error with ESA").build()).build();
}
}
@PUT
@Path("/store-layout/cluster")
@Override
public Response updatePage(EnterpriseStoreCluster storeCluster) {
if (storeCluster == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
} else if (storeCluster.getName() == null || storeCluster.getName().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Cluster name cannot be empty").build()).build();
} else if (storeCluster.getProducts() == null || storeCluster.getProducts().size() < 0) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Products cannot be empty").build()).build();
} else if (storeCluster.getOrderInPage() == null || storeCluster.getOrderInPage().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Cluster order cannot be empty").build()).build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
String id = googleAPIInvoker.updateCluster(enterpriseConfigs.getEnterpriseId(), storeCluster);
storeCluster.setClusterId(id);
return Response.status(Response.Status.OK).entity(storeCluster).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating cluster "
+ storeCluster.getName()).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when updating cluster "
+ storeCluster.getName() + " , due to an error with ESA").build()).build();
}
}
@DELETE
@Path("/store-layout/cluster/{clusterId}/page/{pageId}")
@Override
public Response deleteCluster( @PathParam("clusterId") String clusterId, @PathParam("pageId") String pageId) {
if (clusterId == null || clusterId.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Cluster id cannot be empty").build()).build();
} else if (pageId == null || pageId.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Page id cannot be empty").build()).build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
googleAPIInvoker.deleteCluster(enterpriseConfigs.getEnterpriseId(), pageId, clusterId);
return Response.status(Response.Status.OK).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when deleting cluster "
+ clusterId).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when deleting cluster "
+ clusterId + " , due to an error with ESA").build()).build();
}
}
@GET
@Path("/store-layout/page/{pageId}/clusters")
@Override
public Response getClustersInPage(@PathParam("pageId") String pageId) {
if (pageId == null || pageId.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Page id cannot be empty").build()).build();
}
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
StoreLayoutClustersListResponse response = googleAPIInvoker.getClusters(enterpriseConfigs.getEnterpriseId(), pageId);
if (response == null || response.getCluster() == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Page id cannot be found").build()).build();
}
List<EnterpriseStoreCluster> clusters = new ArrayList<>();
for (StoreCluster cluster : response.getCluster()) {
EnterpriseStoreCluster storeCluster = new EnterpriseStoreCluster();
storeCluster.setClusterId(cluster.getId());
storeCluster.setName(cluster.getName().get(0).getText());
storeCluster.setOrderInPage(cluster.getOrderInPage());
List<String> productIds = new ArrayList<>();
for (String productId : cluster.getProductId()) {
String trimmedPackage = productId.replaceFirst("app:", "");
productIds.add(trimmedPackage);
}
ApplicationManager appManager = AndroidEnterpriseUtils.getAppManagerServer();
List<ApplicationReleaseDTO> packageDetails = appManager.getReleaseByPackageNames(productIds);
List<EnterpriseStorePackages> enterpriseStorePackages = new ArrayList<>();
for (String productId : cluster.getProductId()) {
String trimmedPackage = productId.replaceFirst("app:", "");
EnterpriseStorePackages storePackages = new EnterpriseStorePackages();
storePackages.setPackageId(productId);
for (ApplicationReleaseDTO releaseDTO : packageDetails) {
if (releaseDTO.getPackageName().equalsIgnoreCase(trimmedPackage)) {
storePackages.setIconUrl(releaseDTO.getIconName());
break;
}
}
enterpriseStorePackages.add(storePackages);
}
storeCluster.setProducts(enterpriseStorePackages);
clusters.add(storeCluster);
}
return Response.status(Response.Status.OK).entity(clusters).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching clusters in pageId "
+ pageId).build()).build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching clusters in pageId "
+ pageId + " , due to an error with ESA").build()).build();
} catch (ApplicationManagementException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching all details in PageId "
+ pageId).build()).build();
}
}
@PUT
@Path("/store-layout/page-link")
@Override
public Response updateLinks(EnterpriseStorePageLinks link) {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
googleAPIInvoker.addLinks(enterpriseConfigs.getEnterpriseId(),
link.getPageId(), link.getLinks());
return Response.status(Response.Status.OK).build();
} catch (IOException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching all pages").build())
.build();
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when fetching page "
+ " , Due to an error with ESA").build()).build();
}
}
@Override
@Produces(MediaType.APPLICATION_JSON)
@GET
@Path("/managed-configs/package/{packageName}")
public Response getConfig(@PathParam("packageName") String packageName) {
if (packageName== null || packageName.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Package name is incorrect").build()).build();
}
AndroidEnterpriseManagedConfig managedConfig;
try {
managedConfig = AndroidAPIUtils.getAndroidPluginService().getConfigByPackageName(packageName);
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when saving configs").build()).build();
}
return Response.status(Response.Status.OK).entity(managedConfig).build();
}
@Override
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@POST
@Path("/managed-configs")
public Response addManagedConfigs(AndroidEnterpriseManagedConfig managedConfig) {
if (managedConfig == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
} else if (managedConfig.getPackageName() == null || managedConfig.getPackageName().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Package name is incorrect").build()).build();
} else if (managedConfig.getProfileName() == null || managedConfig.getProfileName().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Profile name is incorrect").build()).build();
}
try {
AndroidAPIUtils.getAndroidPluginService().addConfig(managedConfig);
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when saving configs for "
+ managedConfig.getPackageName()).build()).build();
}
return Response.status(Response.Status.CREATED).build();
}
@Override
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@PUT
@Path("/managed-configs")
public Response updateManagedConfigs(AndroidEnterpriseManagedConfig managedConfig) {
if (managedConfig == null) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Message body is empty or incorrect").build())
.build();
} else if (managedConfig.getProfileName() == null || managedConfig.getProfileName().isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Profile name is incorrect").build()).build();
}
try {
AndroidAPIUtils.getAndroidPluginService().updateMobileDevice(managedConfig);
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when saving configs").build()).build();
}
return Response.status(Response.Status.CREATED).build();
}
@Override
@DELETE
@Path("/managed-configs/mcm/{mcmId}")
public Response deleteManagedConfigs(@PathParam("mcmId") String mcmId) {
if (mcmId == null || mcmId.isEmpty()) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("MCM Id is incorrect").build()).build();
}
try {
AndroidAPIUtils.getAndroidPluginService().deleteMobileDevice(mcmId);
} catch (EnterpriseServiceException e) {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Error when saving configs").build()).build();
}
return Response.status(Response.Status.OK).build();
}
@Override
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@POST
@Path("/change-app")
public Response updateUser(ApplicationPolicyDTO applicationPolicyDTO) {
boolean sentToDevice = false;
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
for (DeviceIdentifier deviceIdentifier : applicationPolicyDTO.getDeviceIdentifierList()) {
try {
AndroidEnterpriseUser userDetail = AndroidAPIUtils.getAndroidPluginService()
.getEnterpriseUserByDevice(deviceIdentifier.getId());
if (userDetail != null && userDetail.getEnterpriseId() != null && !userDetail.getEnterpriseId()
.isEmpty() && userDetail.getEmmUsername() != null) {
if (applicationPolicyDTO.getAction().equals(AndroidConstants.ApplicationInstall.INSTALL)) {
if (applicationPolicyDTO.getPolicy() == null) {
ProfileFeature feature = AndroidDeviceUtils.getEnrollmentFeature(deviceIdentifier);
EnterpriseInstallPolicy enterpriseInstallPolicy = AndroidEnterpriseUtils
.getDeviceAppPolicy(null, feature, userDetail);
List<String> apps = new ArrayList<>();
boolean isAppWhitelisted = false;
for (EnterpriseApp enterpriseApp : enterpriseInstallPolicy.getApps()) {
apps.add(enterpriseApp.getProductId());
String packageName = enterpriseApp.getProductId().replace("app:", "");
if (applicationPolicyDTO.getApplicationDTO().getPackageName().equals(packageName)) {
isAppWhitelisted = true;
}
}
if (enterpriseInstallPolicy.getProductSetBehavior().equals(AndroidConstants
.ApplicationInstall.BEHAVIOUR_WHITELISTED_APPS_ONLY)) {
// This app can only be installed if the app is approved by whitelist to user.
if (!isAppWhitelisted) {
String errorMessage = "App: " + applicationPolicyDTO.getApplicationDTO()
.getPackageName() + " for device " + deviceIdentifier.getId();
log.error(errorMessage);
throw new BadRequestException(
new ErrorResponse.ErrorResponseBuilder().setCode(Response.Status.BAD_REQUEST
.getStatusCode()).setMessage(errorMessage).build());
}
}
googleAPIInvoker.installApps(enterpriseConfigs.getEnterpriseId(), userDetail
.getGoogleUserId(), userDetail.getAndroidPlayDeviceId(), "app:" +
applicationPolicyDTO.getApplicationDTO().getPackageName());
sentToDevice = true;
}
} else if (applicationPolicyDTO.getAction().equals(AndroidConstants.ApplicationInstall.UNINSTALL)) {
googleAPIInvoker.uninstallApps(enterpriseConfigs.getEnterpriseId(), userDetail
.getGoogleUserId(), userDetail.getAndroidPlayDeviceId(), "app:" +
applicationPolicyDTO.getApplicationDTO().getPackageName());
sentToDevice = true;
}
}
} catch (EnterpriseServiceException e) {
String errorMessage = "App install failed for device " + deviceIdentifier.getId();
log.error(errorMessage);
throw new NotFoundException(
new ErrorResponse.ErrorResponseBuilder().setCode(Response.Status.NOT_FOUND
.getStatusCode()).setMessage(errorMessage).build());
} catch (FeatureManagementException e) {
String errorMessage = "Could not fetch effective policy for device " + deviceIdentifier.getId();
log.error(errorMessage);
throw new NotFoundException(
new ErrorResponse.ErrorResponseBuilder().setCode(Response.Status.INTERNAL_SERVER_ERROR
.getStatusCode()).setMessage(errorMessage).build());
}
}
if (sentToDevice) {
return Response.status(Response.Status.OK).build();
} else {
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Could not install on the device of user "
).build()).build();
}
}
@PUT
@Path("/{id}/unenroll")
@Override
public Response unenroll() {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigs();
GoogleAPIInvoker googleAPIInvoker = new GoogleAPIInvoker(enterpriseConfigs.getEsa());
try {
googleAPIInvoker.unenroll(enterpriseConfigs.getEnterpriseId());
} catch (IOException e) {
String errorMessage = "Could not unenroll the enterprise " + enterpriseConfigs.getEnterpriseId();
log.error(errorMessage);
throw new NotFoundException(
new ErrorResponse.ErrorResponseBuilder().setCode(Response.Status.INTERNAL_SERVER_ERROR
.getStatusCode()).setMessage(errorMessage).build());
} catch (EnterpriseServiceException e) {
String errorMessage = "Could not get client to call Google to unenroll enterprise " + enterpriseConfigs.getEnterpriseId();
log.error(errorMessage);
throw new NotFoundException(
new ErrorResponse.ErrorResponseBuilder().setCode(Response.Status.INTERNAL_SERVER_ERROR
.getStatusCode()).setMessage(errorMessage).build());
}
return Response.status(Response.Status.OK).build();
}
}

@ -136,7 +136,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@PUT
@Path("/{id}/pending-operations")
@Override
public Response getPendingOperations(@PathParam("id") String id,
public Response getPendingOperations(@QueryParam("disableGoogleApps") boolean disableGoogleApps,
@PathParam("id") String id,
@HeaderParam("If-Modified-Since") String ifModifiedSince,
List<? extends Operation> resultOperations) {
if (id == null || id.isEmpty()) {
@ -186,7 +187,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
List<? extends Operation> pendingOperations;
try {
pendingOperations = AndroidDeviceUtils.getPendingOperations(deviceIdentifier);
pendingOperations = AndroidDeviceUtils.getPendingOperations(deviceIdentifier, !disableGoogleApps);
} catch (OperationManagementException e) {
String msg = "Issue in retrieving operation management service instance";
log.error(msg, e);

@ -34,6 +34,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementExcept
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.mobile.android.AndroidPluginService;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.exception.BadRequestException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
@ -54,6 +55,18 @@ public class AndroidAPIUtils {
throw new IllegalStateException("Utility class");
}
public static AndroidPluginService getAndroidPluginService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
AndroidPluginService androidPluginService =
(AndroidPluginService) ctx.getOSGiService(AndroidPluginService.class, null);
if (androidPluginService == null) {
String msg = "Android plugin service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return androidPluginService;
}
public static String getAuthenticatedUser() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
String username = threadLocalCarbonContext.getUsername();

@ -62,6 +62,14 @@ public final class AndroidConstants {
public static final String APPLICATION_JSON = "application/json";
public static final String SCOPE = "scope";
public static final String USER_CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress";
public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname";
public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname";
public static final String USER_CLAIM_EMAIL_ADDRESS_PLACEHOLDER = "$email";
public static final String USER_CLAIM_FIRST_NAME_PLACEHOLDER = "$firstName";
public static final String USER_CLAIM_LAST_NAME_PLACEHOLDER = "$lastName";
public final class DeviceProperties {
private DeviceProperties() {
throw new AssertionError();
@ -131,6 +139,7 @@ public final class AndroidConstants {
public static final String DEVICE_REBOOT = "REBOOT";
public static final String UPGRADE_FIRMWARE = "UPGRADE_FIRMWARE";
public static final String NOTIFICATION = "NOTIFICATION";
public static final String POLICY_BUNDLE = "POLICY_BUNDLE";
public static final String WEBCLIP = "WEBCLIP";
public static final String DISENROLL = "DISENROLL";
public static final String MONITOR = "MONITOR";
@ -188,6 +197,8 @@ public final class AndroidConstants {
public static final String DEFAULT_VALIDITY_PERIOD = "3600";
public static final String SUBSCRIPTION_SCOPE = "appm:subscribe";
public static final String ENROLLMENT_APP_INSTALL_UUID = "uuid";
public static final String ENROLLMENT_APP_INSTALL_APP_ID = "appId";
public static final String GOOGLE_POLICY_PAYLOAD = "installGooglePolicyPayload";
public static final String ENROLLMENT_APP_INSTALL_CODE = "enrollmentAppInstall";
public static final String ENCODING = "UTF-8";
public static final String AT = "@";
@ -198,6 +209,9 @@ public final class AndroidConstants {
public static final String ENROLLMENT_APP_INSTALL_URL = "/api/application-mgt-store/v1.0/subscription/{uuid}/devices/install";
public static final String AUTHORIZATION = "Authorization";
public static final String AUTHORIZATION_HEADER_VALUE = "Bearer ";
public static final String BEHAVIOUR_WHITELISTED_APPS_ONLY = "whitelist";
public static final String INSTALL = "INSTALL";
public static final String UNINSTALL = "UNINSTALL";
}
public final class ErrorMessages {

@ -64,6 +64,8 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
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.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
@ -76,13 +78,22 @@ 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.impl.EnterpriseServiceException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.mdm.services.android.bean.DeviceState;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseConfigs;
import org.wso2.carbon.mdm.services.android.bean.ErrorListItem;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseApp;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseInstallPolicy;
import org.wso2.carbon.mdm.services.android.common.GoogleAPIInvoker;
import org.wso2.carbon.mdm.services.android.exception.BadRequestException;
import org.wso2.carbon.policy.mgt.common.FeatureManagementException;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
import org.wso2.carbon.user.api.UserStoreException;
import javax.validation.ConstraintViolation;
@ -268,13 +279,100 @@ public class AndroidDeviceUtils {
}
public static List<? extends Operation> getPendingOperations
(DeviceIdentifier deviceIdentifier) throws OperationManagementException {
(DeviceIdentifier deviceIdentifier, boolean handleGoogleAps) throws OperationManagementException {
List<? extends Operation> operations;
operations = AndroidAPIUtils.getDeviceManagementService().getPendingOperations(deviceIdentifier);
if (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
for (JsonElement appElement : appListArray) {
JsonElement googlePolicyPayload = appElement.getAsJsonObject().
get(AndroidConstants.ApplicationInstall.GOOGLE_POLICY_PAYLOAD);
if (googlePolicyPayload != null) {
containsGoogleAppPolicy = true;
sendPayloadToGoogle(payload, deviceIdentifier);
break;
}
}
}
}
}
}
}
/**
* Sends the app install policy to Google
* @param payload policy profile
* @param deviceIdentifier device to apply policy
*/
private static void sendPayloadToGoogle(String payload, DeviceIdentifier deviceIdentifier) {
try {
EnterpriseConfigs enterpriseConfigs = AndroidEnterpriseUtils.getEnterpriseConfigsFromGoogle();
if (enterpriseConfigs != null && 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) {
if (payload != null) {
// ProfileFeature feature = AndroidDeviceUtils.getEnrollmentPolicy(deviceIdentifier);
EnterpriseInstallPolicy enterpriseInstallPolicy = AndroidEnterpriseUtils
.getDeviceAppPolicy(payload, null, userDetail);
List<String> apps = new ArrayList<>();
for (EnterpriseApp enterpriseApp : enterpriseInstallPolicy.getApps()) {
apps.add(enterpriseApp.getProductId());
}
googleAPIInvoker.approveAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail
.getGoogleUserId(), apps, enterpriseInstallPolicy.getProductSetBehavior());
googleAPIInvoker.updateAppsForUser(enterpriseConfigs.getEnterpriseId(), userDetail.getGoogleUserId(),
AndroidEnterpriseUtils.convertToDeviceInstance(enterpriseInstallPolicy));
// for (EnterpriseApp enterpriseApp : enterpriseInstallPolicy.getApps()) {
// googleAPIInvoker.addManagedConfigForDevice(enterpriseConfigs.getEnterpriseId(), userDetail
// .getGoogleUserId(), enterpriseInstallPolicy.getAndroidId(), enterpriseApp.getProductId());
// }
}
}
}
} catch (EnterpriseServiceException e) {
String errorMessage = "App install failed for device " + deviceIdentifier.getId();
log.error(errorMessage);
}
}
private static void updateApplicationList(Operation operation, DeviceIdentifier deviceIdentifier)
throws ApplicationManagementException {
// Parsing json string to get applications list.
@ -624,7 +722,7 @@ public class AndroidDeviceUtils {
public static void updateDisEnrollOperationStatus(DeviceIdentifier deviceIdentifier)
throws DeviceManagementException {
try {
List<? extends Operation> pendingOperations = getPendingOperations(deviceIdentifier);
List<? extends Operation> pendingOperations = getPendingOperations(deviceIdentifier, false);
if (pendingOperations != null && !pendingOperations.isEmpty()) {
for (Operation operation : pendingOperations) {
operation.setStatus(Operation.Status.ERROR);
@ -638,4 +736,53 @@ public class AndroidDeviceUtils {
throw new DeviceManagementException(msg, e);
}
}
public static String getAndroidConfig(String key) throws DeviceManagementException {
String value = null;
PlatformConfiguration configuration = AndroidAPIUtils.getDeviceManagementService().
getConfiguration(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
if (configuration != null && configuration.getConfiguration() != null && configuration
.getConfiguration().size() > 0) {
List<ConfigurationEntry> configurations = configuration.getConfiguration();
for (ConfigurationEntry configurationEntry : configurations) {
if (configurationEntry.getName().equals(key)) {
value = (String)configurationEntry.getValue();
break;
}
}
}
return value;
}
public static String getAndroidConfig(PlatformConfiguration configuration, String key) {
String value = null;
if (configuration != null && configuration.getConfiguration() != null && configuration
.getConfiguration().size() > 0) {
List<ConfigurationEntry> configurations = configuration.getConfiguration();
for (ConfigurationEntry configurationEntry : configurations) {
if (configurationEntry.getName().equals(key)) {
value = (String)configurationEntry.getValue();
break;
}
}
}
return value;
}
public static ProfileFeature getEnrollmentFeature(DeviceIdentifier deviceIdentifier) throws
FeatureManagementException {
PolicyManagerService policyManagerService = AndroidAPIUtils.getPolicyManagerService();
List<ProfileFeature> effectiveProfileFeatures= policyManagerService.getEffectiveFeatures(deviceIdentifier);
if (effectiveProfileFeatures != null) {
for (ProfileFeature feature : effectiveProfileFeatures) {
if (AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_FEATURE_CODE
.equals(feature.getFeatureCode())) {
return feature;
}
}
}
return null;
}
}

@ -0,0 +1,468 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.mdm.services.android.util;
import com.google.api.services.androidenterprise.model.AppVersion;
import com.google.api.services.androidenterprise.model.AutoInstallConstraint;
import com.google.api.services.androidenterprise.model.AutoInstallPolicy;
import com.google.api.services.androidenterprise.model.ConfigurationVariables;
import com.google.api.services.androidenterprise.model.Device;
import com.google.api.services.androidenterprise.model.ManagedConfiguration;
import com.google.api.services.androidenterprise.model.Policy;
import com.google.api.services.androidenterprise.model.Product;
import com.google.api.services.androidenterprise.model.ProductPolicy;
import com.google.api.services.androidenterprise.model.ProductsListResponse;
import com.google.api.services.androidenterprise.model.VariableSet;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.application.mgt.common.ApplicationArtifact;
import org.wso2.carbon.device.application.mgt.common.LifecycleChanger;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.response.Application;
import org.wso2.carbon.device.application.mgt.common.response.Category;
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper;
import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
import org.wso2.carbon.device.mgt.mobile.android.impl.EnterpriseServiceException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseManagedConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import org.wso2.carbon.mdm.services.android.bean.BasicUserInfo;
import org.wso2.carbon.mdm.services.android.bean.EnterpriseConfigs;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseApp;
import org.wso2.carbon.mdm.services.android.bean.wrapper.EnterpriseInstallPolicy;
import org.wso2.carbon.mdm.services.android.exception.NotFoundException;
import org.wso2.carbon.mdm.services.android.exception.UnexpectedServerErrorException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AndroidEnterpriseUtils {
private static Log log = LogFactory.getLog(AndroidEnterpriseUtils.class);
private static List<String> templates = Arrays.asList(AndroidConstants
.USER_CLAIM_EMAIL_ADDRESS_PLACEHOLDER, AndroidConstants.USER_CLAIM_FIRST_NAME_PLACEHOLDER,
AndroidConstants.USER_CLAIM_LAST_NAME_PLACEHOLDER);
public static Device convertToDeviceInstance(EnterpriseInstallPolicy enterpriseInstallPolicy)
throws EnterpriseServiceException {
Device device = new Device();
device.setManagementType(enterpriseInstallPolicy.getManagementType());
device.setKind(enterpriseInstallPolicy.getKind());
device.setAndroidId(enterpriseInstallPolicy.getAndroidId());
Policy policy = new Policy();
List<ProductPolicy> policyList = new ArrayList<>();
for (EnterpriseApp app : enterpriseInstallPolicy.getApps()) {
ProductPolicy productPolicy = new ProductPolicy();
AutoInstallPolicy autoInstallPolicy = new AutoInstallPolicy();
autoInstallPolicy.setAutoInstallMode(app.getAutoInstallMode());
autoInstallPolicy.setAutoInstallPriority(app.getAutoInstallPriority());
List<AutoInstallConstraint> autoInstallConstraintList = new ArrayList<>();
AutoInstallConstraint autoInstallConstraint = new AutoInstallConstraint();
autoInstallConstraint.setChargingStateConstraint(app.getChargingStateConstraint());
autoInstallConstraint.setDeviceIdleStateConstraint(app.getDeviceIdleStateConstraint());
autoInstallConstraint.setNetworkTypeConstraint(app.getNetworkTypeConstraint());
autoInstallConstraintList.add(autoInstallConstraint);
autoInstallPolicy.setAutoInstallConstraint(autoInstallConstraintList);
productPolicy.setAutoInstallPolicy(autoInstallPolicy);
productPolicy.setProductId(app.getProductId());
// TODO: Cache this against package name
AndroidEnterpriseManagedConfig configs = AndroidAPIUtils.getAndroidPluginService()
.getConfigByPackageName(app.getProductId().replaceFirst("app:", ""));
if (configs != null && configs.getMcmId() != null) {
ManagedConfiguration managedConfiguration = new ManagedConfiguration();
ConfigurationVariables configurationVariables = new ConfigurationVariables();
configurationVariables.setKind("androidenterprise#configurationVariables");
configurationVariables.setMcmId(configs.getMcmId());
List<VariableSet> variableSets = new ArrayList<>();
BasicUserInfo userInfo = getBasicUserInfo(PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername());
for (String key : templates) {
VariableSet variableSet = new VariableSet();
variableSet.setKind("androidenterprise#variableSet");
variableSet.setPlaceholder(key);
String value = getPlaceholderValue(userInfo, key);
if (value == null) {
continue;
}
variableSet.setUserValue(value);
variableSets.add(variableSet);
}
if (variableSets != null && variableSets.size() > 0) {
configurationVariables.setVariableSet(variableSets);
}
managedConfiguration.setConfigurationVariables(configurationVariables);
productPolicy.setManagedConfiguration(managedConfiguration);
}
policyList.add(productPolicy);
}
policy.setProductPolicy(policyList);
policy.setAutoUpdatePolicy(enterpriseInstallPolicy.getAutoUpdatePolicy());
policy.setProductAvailabilityPolicy(enterpriseInstallPolicy.getProductAvailabilityPolicy());
device.setPolicy(policy);
return device;
}
private static String getPlaceholderValue(BasicUserInfo userInfo, String key) {
if (userInfo != null) {
switch (key) {
case AndroidConstants.USER_CLAIM_EMAIL_ADDRESS_PLACEHOLDER:
return userInfo.getEmailAddress();
case AndroidConstants.USER_CLAIM_FIRST_NAME_PLACEHOLDER:
return userInfo.getFirstname();
case AndroidConstants.USER_CLAIM_LAST_NAME_PLACEHOLDER:
return userInfo.getLastname();
}
}
return null;
}
private static UserStoreManager getUserStoreManager() throws EnterpriseServiceException {
RealmService realmService;
UserStoreManager userStoreManager = null;
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
try {
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
} catch (UserStoreException e) {
String msg = "Could not create user store manager.";
log.error(msg);
throw new EnterpriseServiceException(msg, e);
}
return userStoreManager;
}
private static BasicUserInfo getBasicUserInfo(String username) throws EnterpriseServiceException {
UserStoreManager userStoreManager = getUserStoreManager();
try {
if (!userStoreManager.isExistingUser(username)) {
if (log.isDebugEnabled()) {
log.debug("User by username: " + username + " does not exist.");
}
return null;
}
} catch (UserStoreException e) {
String msg = "Could not get user details of user " + username;
log.error(msg);
throw new EnterpriseServiceException(msg, e);
}
BasicUserInfo userInfo = new BasicUserInfo();
userInfo.setUsername(username);
try {
userInfo.setEmailAddress(userStoreManager.getUserClaimValue(username, AndroidConstants.USER_CLAIM_EMAIL_ADDRESS, null));
userInfo.setFirstname(userStoreManager.getUserClaimValue(username, AndroidConstants.USER_CLAIM_FIRST_NAME, null));
userInfo.setFirstname(userStoreManager.getUserClaimValue(username, AndroidConstants.USER_CLAIM_LAST_NAME, null));
} catch (UserStoreException e) {
String msg = "Could not get claims of user " + username;
log.error(msg);
throw new EnterpriseServiceException(msg, e);
}
return userInfo;
}
public static EnterpriseConfigs getEnterpriseConfigs() {
EnterpriseConfigs enterpriseConfigs = getEnterpriseConfigsFromGoogle();
if (enterpriseConfigs.getErrorResponse() != null) {
if (enterpriseConfigs.getErrorResponse().getCode() == 500l) {
throw new UnexpectedServerErrorException(enterpriseConfigs.getErrorResponse());
} else if (enterpriseConfigs.getErrorResponse().getCode() == 500l) {
throw new NotFoundException(enterpriseConfigs.getErrorResponse());
}
}
return enterpriseConfigs;
}
public static EnterpriseConfigs getEnterpriseConfigsFromGoogle() {
PlatformConfiguration configuration = null;
EnterpriseConfigs enterpriseConfigs = new EnterpriseConfigs();
try {
configuration = AndroidAPIUtils.getDeviceManagementService().
getConfiguration(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
} catch (DeviceManagementException e) {
String errorMessage = "Error while fetching tenant configurations for tenant " +
PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
log.error(errorMessage);
// Error is being used in enterprise APIs as well as from getpending operations which should not fail as
// these errors can cause due to issues misconfigurations in policy/esa configs which can cause to break all
// operations, if the error is thrown to cfx error handler
enterpriseConfigs.setErrorResponse(new ErrorResponse.ErrorResponseBuilder().setCode(500l)
.setMessage(errorMessage).build());
}
String enterpriseId = AndroidDeviceUtils.getAndroidConfig(configuration,"enterpriseId");
String esa = AndroidDeviceUtils.getAndroidConfig(configuration,"esa");
if (enterpriseId == null || enterpriseId.isEmpty() || esa == null || esa.isEmpty()) {
String errorMessage = "Tenant is not configured to handle Android for work. Please contact Entgra.";
log.error(errorMessage);
enterpriseConfigs.setErrorResponse(new ErrorResponse.ErrorResponseBuilder().setCode(404l)
.setMessage(errorMessage).build());
}
enterpriseConfigs.setEnterpriseId(enterpriseId);
enterpriseConfigs.setEsa(esa);
return enterpriseConfigs;
}
public static ApplicationManager getAppManagerServer() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
return (ApplicationManager) ctx.getOSGiService(ApplicationManager.class, null);
}
public static void persistApp(ProductsListResponse productListResponse) throws ApplicationManagementException {
ApplicationManager applicationManager = getAppManagerServer();
List<Category> categories = applicationManager.getRegisteredCategories();
if (productListResponse != null && productListResponse.getProduct() != null
&& productListResponse.getProduct().size() > 0) {
for (Product product : productListResponse.getProduct()) {
if (product.getAppVersion() == null) { // This is to handled removed apps from playstore
continue;
}
// Generate App wrapper
PublicAppWrapper publicAppWrapper = new PublicAppWrapper();
PublicAppReleaseWrapper appReleaseWrapper = new PublicAppReleaseWrapper();
publicAppWrapper.setName(product.getTitle());
publicAppWrapper.setDescription(product.getDescription());
publicAppWrapper.setCategories(Arrays.asList(new String[]{"GooglePlaySyncedApp"}));//Default category
for (Category category : categories) {
if (product.getCategory() == null) {
publicAppWrapper.setCategories(Arrays.asList(new String[]{"GooglePlaySyncedApp"}));
break;
} else if (product.getCategory().equalsIgnoreCase(category.getCategoryName())) {
publicAppWrapper.setCategories(Arrays.asList(new String[]{category.getCategoryName(), "GooglePlaySyncedApp"}));
break;
}
}
if (product.getProductPricing().equalsIgnoreCase("free")) {
publicAppWrapper.setSubMethod("FREE");
} else {
publicAppWrapper.setSubMethod("PAID");
}
// TODO: purchase an app from Playstore and see how to capture the real value for price field.
publicAppWrapper.setPaymentCurrency("$");
appReleaseWrapper.setPrice(1.0);
publicAppWrapper.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
appReleaseWrapper.setDescription(product.getRecentChanges());
appReleaseWrapper.setReleaseType("ga");
appReleaseWrapper.setVersion(getAppString(product.getAppVersion()));
appReleaseWrapper.setPackageName(product.getProductId().replaceFirst("app:", ""));
appReleaseWrapper.setSupportedOsVersions(String.valueOf(product.getMinAndroidSdkVersion()) + "-ALL");
publicAppWrapper.setPublicAppReleaseWrappers(Arrays.asList(new PublicAppReleaseWrapper[]{appReleaseWrapper}));
// Generate artifacts
ApplicationArtifact applicationArtifact = new ApplicationArtifact();
String iconName = product.getIconUrl().split(".com/")[1];
applicationArtifact.setIconName(iconName);
InputStream iconInputStream = getInputStream(iconName, product.getIconUrl());
applicationArtifact.setIconStream(iconInputStream);
Map<String, InputStream> screenshotMap = new HashMap<>();
int numberOfScreenShots = 3;// This is to handle some apps in playstore without 3 screenshots.
if (product.getScreenshotUrls() != null) {
if (product.getScreenshotUrls().size() < 3) {
numberOfScreenShots = product.getScreenshotUrls().size();
}
for (int y = 1; y < 4; y++) {
int screenshotNumber = y - 1;
if (y > numberOfScreenShots) {
screenshotNumber = 0;
}
String screenshot = product.getScreenshotUrls().get(screenshotNumber);
String screenshotName = screenshot.split(".com/")[1];
InputStream screenshotInputStream = getInputStream(screenshotName, screenshot);
screenshotMap.put(screenshotName, screenshotInputStream);
}
} else { // Private apps doesn't seem to send screenshots. Handling it.
for (int a = 0; a < 3; a++) {
String screenshot = product.getIconUrl();
String screenshotName = screenshot.split(".com/")[1];
InputStream screenshotInputStream = getInputStream(screenshotName, screenshot);
screenshotMap.put(screenshotName, screenshotInputStream);
}
}
applicationArtifact.setScreenshots(screenshotMap);
Application application = applicationManager.createPublicApp(publicAppWrapper, applicationArtifact);
if (application != null && (application.getApplicationReleases().get(0).getCurrentStatus() == null
|| application.getApplicationReleases().get(0).getCurrentStatus().equals("CREATED"))) {
String uuid = application.getApplicationReleases().get(0).getUuid();
LifecycleChanger lifecycleChanger = new LifecycleChanger();
lifecycleChanger.setAction("IN-REVIEW");
applicationManager.changeLifecycleState(uuid, lifecycleChanger);
lifecycleChanger.setAction("APPROVED");
applicationManager.changeLifecycleState(uuid, lifecycleChanger);
lifecycleChanger.setAction("PUBLISHED");
applicationManager.changeLifecycleState(uuid, lifecycleChanger);
}
}
}
}
private static InputStream getInputStream(String filename, String url) throws ApplicationManagementException {
URL website;
try {
website = new URL(url);
} catch (MalformedURLException e) {
String msg = "Error occurred while converting the url " + url;
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
ReadableByteChannel rbc = null;
FileOutputStream fos = null;
try {
rbc = Channels.newChannel(website.openStream());
fos = new FileOutputStream(System.getProperty("java.io.tmpdir")
+ File.separator + filename);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}catch (IOException e) {
String msg = "Error occurred while opening stream for url " + url;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
try {
fos.close();
rbc.close();
} catch (IOException e) {}
}
File file = new File(System.getProperty("java.io.tmpdir") + File.separator + filename);
InputStream targetStream;
try {
targetStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
String msg = "Error occurred while reading the tmp file " + System.getProperty("java.io.tmpdir")
+ File.separator + filename;
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
file.deleteOnExit();
return targetStream;
}
private static String getAppString(List<AppVersion> appVersions) {
int highestVersionCode = 0;
String highestVersionString = null;
for (AppVersion appVersion : appVersions) {
if (appVersion.getIsProduction() && appVersion.getVersionCode() > highestVersionCode) {
highestVersionCode = appVersion.getVersionCode();
highestVersionString = appVersion.getVersionString();
}
}
return highestVersionString;
}
public static EnterpriseInstallPolicy getDeviceAppPolicy(String appPolicy,
ProfileFeature feature,
AndroidEnterpriseUser userDetail) {
EnterpriseInstallPolicy enterpriseInstallPolicy = new EnterpriseInstallPolicy();
List<EnterpriseApp> apps = new ArrayList<>();
JsonElement appListElement;
if (appPolicy == null) {
appListElement = new JsonParser().parse(feature.getContent().toString()).getAsJsonObject()
.get(AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_CODE);
} else {
appListElement = new JsonParser().parse(appPolicy).getAsJsonObject()
.get(AndroidConstants.ApplicationInstall.ENROLLMENT_APP_INSTALL_CODE);
}
JsonArray appListArray = appListElement.getAsJsonArray();
JsonObject googlePolicyPayload = appListArray.get(0).getAsJsonObject();
// get(AndroidConstants.ApplicationInstall.GOOGLE_POLICY_PAYLOAD).getAsString()).getAsJsonObject();
enterpriseInstallPolicy.setAutoUpdatePolicy(googlePolicyPayload.get("autoUpdatePolicy").getAsString());
enterpriseInstallPolicy.setProductSetBehavior(googlePolicyPayload.get("productSetBehavior").getAsString());
// enterpriseInstallPolicy.setProductAvailabilityPolicy(googlePolicyPayload.get("productAvailabilityPolicy").getAsString());
enterpriseInstallPolicy.setManagementType("managedProfile");
enterpriseInstallPolicy.setKind("androidenterprise#device");
enterpriseInstallPolicy.setAndroidId(userDetail.getAndroidPlayDeviceId());
enterpriseInstallPolicy.setUsername(userDetail.getEmmUsername());
for (JsonElement appElement : appListArray) {
JsonElement policy = appElement.getAsJsonObject().
get(AndroidConstants.ApplicationInstall.GOOGLE_POLICY_PAYLOAD);
if (policy != null) {
JsonObject googlePolicyForApp = new JsonParser().parse(policy.getAsString()).getAsJsonObject();
EnterpriseApp enterpriseApp = new EnterpriseApp();
enterpriseApp.setProductId("app:" + googlePolicyForApp.get("packageName").getAsString());
enterpriseApp.setAutoInstallMode(googlePolicyForApp.get("autoInstallMode").getAsString());
enterpriseApp.setAutoInstallPriority(googlePolicyForApp.get("autoInstallPriority").getAsInt());
enterpriseApp.setChargingStateConstraint(googlePolicyForApp.get("chargingStateConstraint").getAsString());
enterpriseApp.setDeviceIdleStateConstraint(googlePolicyForApp.get("deviceIdleStateConstraint").getAsString());
enterpriseApp.setNetworkTypeConstraint(googlePolicyForApp.get("networkTypeConstraint").getAsString());
apps.add(enterpriseApp);
}
}
enterpriseInstallPolicy.setApps(apps);
return enterpriseInstallPolicy;
}
}

@ -26,6 +26,7 @@
<ref bean="deviceManagementService"/>
<ref bean="deviceManagementAdminService"/>
<ref bean="eventReceiverService"/>
<ref bean="androidEnterprise"/>
<ref bean="deviceTypeConfigurationService"/>
<ref bean="swaggerResource"/>
</jaxrs:serviceBeans>
@ -63,6 +64,7 @@
<bean id="deviceManagementAdminService" class="org.wso2.carbon.mdm.services.android.services.impl.DeviceManagementAdminServiceImpl"/>
<bean id="eventReceiverService" class="org.wso2.carbon.mdm.services.android.services.impl.EventReceiverServiceImpl"/>
<bean id="deviceTypeConfigurationService" class="org.wso2.carbon.mdm.services.android.services.impl.DeviceTypeConfigurationServiceImpl"/>
<bean id="androidEnterprise" class="org.wso2.carbon.mdm.services.android.services.impl.AndroidEnterpriseServiceImpl"/>
<bean id="jsonProvider" class="org.wso2.carbon.mdm.services.android.common.GsonMessageBodyHandler"/>
<bean id="errorHandler" class="org.wso2.carbon.mdm.services.android.common.ErrorHandler"/>
<cxf:bus>

@ -113,7 +113,7 @@ public class DeviceManagementServiceTests {
public void testGetPendingOperationsForNullDevice()
throws DeviceManagementException, OperationManagementException, InvalidDeviceException {
Response response = deviceManagementService
.getPendingOperations(null, null, null);
.getPendingOperations(true, null, null, null);
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
}
@ -123,7 +123,7 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, OperationManagementException, InvalidDeviceException {
mockDeviceManagementService();
Response response = deviceManagementService
.getPendingOperations("1234", null, null);
.getPendingOperations(true, "1234", null, null);
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
}
@ -133,7 +133,7 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, OperationManagementException, InvalidDeviceException {
mockDeviceManagementService();
Response response = deviceManagementService
.getPendingOperations(TestUtils.getDeviceId(), null, null);
.getPendingOperations(true, TestUtils.getDeviceId(), null, null);
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
}
@ -144,7 +144,7 @@ public class DeviceManagementServiceTests {
mockDeviceManagementService();
mockPolicyManagerService();
Response response = deviceManagementService
.getPendingOperations(TestUtils.getDeviceId(), null,
.getPendingOperations(true, TestUtils.getDeviceId(), null,
TestUtils.getSuccessMonitorOperationResponse());
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
@ -156,7 +156,7 @@ public class DeviceManagementServiceTests {
mockDeviceManagementService();
mockApplicationManagerService();
Response response = deviceManagementService
.getPendingOperations(TestUtils.getDeviceId(), null,
.getPendingOperations(true, TestUtils.getDeviceId(), null,
TestUtils.getSuccessApplicationOperationResponse());
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
@ -168,7 +168,7 @@ public class DeviceManagementServiceTests {
mockDeviceManagementService();
mockDeviceInformationManagerService();
Response response = deviceManagementService
.getPendingOperations(TestUtils.getDeviceId(), null,
.getPendingOperations(true, TestUtils.getDeviceId(), null,
TestUtils.getSuccessInfoOperationResponse());
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
@ -179,7 +179,7 @@ public class DeviceManagementServiceTests {
throws DeviceManagementException, OperationManagementException, InvalidDeviceException {
mockDeviceManagementService();
Response response = deviceManagementService
.getPendingOperations(TestUtils.getDeviceId(), null,
.getPendingOperations(true, TestUtils.getDeviceId(), null,
TestUtils.getInProgressOperationResponse());
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
@ -191,7 +191,7 @@ public class DeviceManagementServiceTests {
mockDeviceManagementService();
mockNotificationManagementService();
Response response = deviceManagementService
.getPendingOperations(TestUtils.getDeviceId(), null,
.getPendingOperations(true, TestUtils.getDeviceId(), null,
TestUtils.getErrorOperationResponse());
Assert.assertNotNull(response);
Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());

@ -133,6 +133,18 @@ var androidOperationModule = function () {
"passcodePolicyPasscodeHistory": operationPayload["pinHistory"],
"passcodePolicyMaxFailedAttempts": operationPayload["maxFailedAttempts"]
};
if (operationPayload["passcodePolicyWPExist"] === true) {
payload["passcodePolicyWPExist"] = operationPayload["passcodePolicyWPExist"];
payload["passcodePolicyAllowSimpleWP"] = operationPayload.workProfilePasscode["passcodePolicyAllowSimpleWP"];
payload["passcodePolicyRequireAlphanumericWP"] = operationPayload.workProfilePasscode["passcodePolicyRequireAlphanumericWP"];
payload["passcodePolicyMinLengthWP"] = operationPayload.workProfilePasscode["passcodePolicyMinLengthWP"];
payload["passcodePolicyMinComplexCharsWP"] = operationPayload.workProfilePasscode["passcodePolicyMinComplexCharsWP"];
payload["passcodePolicyMaxPasscodeAgeInDaysWP"] = operationPayload.workProfilePasscode["passcodePolicyMaxPasscodeAgeInDaysWP"];
payload["passcodePolicyPasscodeHistoryWP"] = operationPayload.workProfilePasscode["passcodePolicyPasscodeHistoryWP"];
payload["passcodePolicyMaxFailedAttemptsWP"] = operationPayload.workProfilePasscode["passcodePolicyMaxFailedAttemptsWP"];
} else {
payload["passcodePolicyWPExist"] = operationPayload["passcodePolicyWPExist"];
}
break;
case androidOperationConstants["CAMERA_OPERATION_CODE"]:
payload = operationPayload;
@ -494,6 +506,21 @@ var androidOperationModule = function () {
"maxFailedAttempts": operationData["passcodePolicyMaxFailedAttempts"]
}
};
workProfilePasscode = {};
if (operationData["passcodePolicyWPExist"] === true) {
payload.operation["passcodePolicyWPExist"] = operationData["passcodePolicyWPExist"];
workProfilePasscode["passcodePolicyAllowSimpleWP"] = operationData["passcodePolicyAllowSimpleWP"];
workProfilePasscode["passcodePolicyRequireAlphanumericWP"] = operationData["passcodePolicyRequireAlphanumericWP"];
workProfilePasscode["passcodePolicyMinLengthWP"] = operationData["passcodePolicyMinLengthWP"];
workProfilePasscode["passcodePolicyMinComplexCharsWP"] = operationData["passcodePolicyMinComplexCharsWP"];
workProfilePasscode["passcodePolicyMaxPasscodeAgeInDaysWP"] = operationData["passcodePolicyMaxPasscodeAgeInDaysWP"];
workProfilePasscode["passcodePolicyPasscodeHistoryWP"] = operationData["passcodePolicyPasscodeHistoryWP"];
workProfilePasscode["passcodePolicyMaxFailedAttemptsWP"] = operationData["passcodePolicyMaxFailedAttemptsWP"] ;
payload.operation.workProfilePasscode = workProfilePasscode;
} else {
payload["passcodePolicyWPExist"] = operationData["passcodePolicyWPExist"];
}
break;
break;
case androidOperationConstants["APPLICATION_OPERATION_CODE"]:
payload = {
@ -1018,22 +1045,65 @@ var androidOperationModule = function () {
if (value) {
if (operationDataObj.hasClass("specific-enrollment-app-install")) {
if ($(".enrollment-app-install-input", this).length > 0) {
$("select#enrollment-app-install-table_length").val("100").change();
for (i=0; i<value.length; i++) {
$(".enrollment-app-install-input", this).each(function() {
childInput = $(this);
var childInputKey = childInput.data("child-key");
if (childInputKey === "appId" && value[i].appId === childInput.val()) {
childInput.parent().find("a").filterByData("click-event", "add-enrollment-app").click();
if (childInputKey == "productSetBehavior" && value[i].productSetBehavior) {
$('select#product-set-behaviour').attr('data-product-set-behavior',
value[i].productSetBehavior);
}
if (childInputKey == "autoUpdatePolicy" && value[i].autoUpdatePolicy) {
$('select#auto-update-policy').attr('data-auto-update-policy',
value[i].autoUpdatePolicy);
}
if (childInputKey === "installGooglePolicy"
&& value[i].appId === childInput[0].getAttribute("data-app-id")){
if (value[i].installGooglePolicy) {
childInput.parent().find("input").filterByData("child-key", "installGooglePolicyPayload").val(value[i].installGooglePolicyPayload);
childInput.filterByData("child-key", "installGooglePolicy").prop('checked', true);
childInput.parents("tr").last().find("input").each(function () {
if(!$(this).hasClass("child-input")) {
$(this).addClass("child-input");
}
});
}
} else if (childInputKey === "enrollmentAppInstall"
&& value[i].appId === childInput[0].getAttribute("data-app-id")){
if (value[i].enrollmentAppInstall) {
childInput.filterByData("child-key", "enrollmentAppInstall").prop('checked', true);
childInput.parents("tr").last().find("input").each(function () {
if(!$(this).hasClass("child-input")) {
$(this).addClass("child-input");
}
});
}
}
});
}
} else {
$('[data-add-form-container="#enrollment-app-install-grid"]').empty();
for (i=0; i<value.length; i++) {
var enrollmentAppInstallInput = '<input type="checkbox" disabled/>';
if (value[i].enrollmentAppInstall) {
enrollmentAppInstallInput = '<input type="checkbox" checked disabled/>';
}
var installGooglePolicy = '<input type="checkbox" disabled/>';
if (value[i].installGooglePolicy) {
installGooglePolicy = '<input type="checkbox" checked disabled/>';
}
var content = '<tr><td data-title="enrollment-app-install-app-name">'
+ value[i].appName + '</td><td data-title="enrollment-app-install-app-type">'
+ value[i].type + '</td><td data-title="enrollment-app-install-version">'
+ value[i].version + '</td></tr>';
+ value[i].version + '</td>'
+ '<td>' + enrollmentAppInstallInput + '</td>'
+ '<td>' + installGooglePolicy + '</td>'
+'</tr>';
$('[data-add-form-container="#enrollment-app-install-grid"]').append(content);
}
}

@ -201,12 +201,92 @@
</select>
</div>
</div>
<!-- End of KIOSK Configs -->
<!-- Android For Work Configurations -->
<div class="wr-input-control wr-btn-grp">
<button id="save-android-btn" class="wr-btn">Save</button>
</div>
<br><br>
<h4>
Android For Work Configurations
<hr>
</h4>
<label class="wr-input-label" for="afw-configure">
Configure Android For Work Integration
<span class="helper" title="Configure Android For Work Integration">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label><br><br>
<div class="wr-input-control">
<label class="wr-input-label" for="afw-server-details">
Server details provided by EMM vendor
</label>
<input id="afw-server-details" type="text" class="form-control" >
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="afw-backend-token">
Token
</label>
<input id="afw-backend-token" type="text" class="form-control" >
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="afw-esa">
ESA
</label>
<input id="afw-esa" type="text" class="form-control" >
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="afw-enterprise-id">
Enterprise ID
</label>
<input id="afw-enterprise-id" type="text" class="form-control" >
</div>
<div class="wr-input-control">
<div>
<button id="afw-configure" class="wr-btn">Begin configuration</button>
</div>
</div>
<br><br>
<h4>
Unenroll from EMM
</h4>
<div class="wr-input-control">
<label class="wr-input-label" for="afw-server-details">
Unregister your enterprise from EMM.
<br>WARNING: This action cannot be undone.
</label>
<button id="afw-unenroll" class="wr-btn">Unenroll</button>
</div>
<div id="remove-unenroll-modal-content" class="hide">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>Do you really want to unenroll? This cannot be undone.</h3>
<div class="buttons">
<a href="#" id="remove-unenroll-yes-link" class="btn-operations">
Yes
</a>
<a href="#" id="remove-unenroll-cancel-link" class="btn-operations btn-default"
data-dismiss="modal">
Cancel
</a>
</div>
<br>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /android -->

@ -92,6 +92,16 @@ var kioskConfigs = {
"serverIP" : "android.app.extra.serverIp"
};
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
$(document).ready(function () {
$("#fcm-inputs").hide();
tinymce.init({
@ -109,6 +119,12 @@ $(document).ready(function () {
var androidConfigAPI = "/api/device-mgt/android/v1.0/configuration";
var enterpriseSuccess = getParameterByName('enterprise-success');
if (enterpriseSuccess) {
$("#config-save-form").addClass("hidden");
$("#record-created-msg").removeClass("hidden");
}
/**
* Following requests would execute
* on page load event of platform configuration page in WSO2 EMM Console.
@ -152,11 +168,16 @@ $(document).ready(function () {
$("input#android-kiosk-config-download-url").val(config.value);
} else if (config.name === kioskConfigs["skipEncryption"]) {
$("#android-kiosk-config-encryption").val(config.value);
} else if (config.name === "esa") {
$("#afw-esa").val(config.value);
} else if (config.name === "enterpriseId") {
$("#afw-enterprise-id").val(config.value);
} else if (config.name === kioskConfigs["defaultOwnership"]) {
$("#android-kiosk-config-defaultOwner").val(config.value);
} else if (config.name === kioskConfigs["serverIP"]) {
$("#android-kiosk-config-server-ip").val(config.value);
}
}
}
}, function (data) {
@ -191,6 +212,8 @@ $(document).ready(function () {
var androidLicense = tinyMCE.activeEditor.getContent();
var errorMsgWrapper = "#android-config-error-msg";
var errorMsg = "#android-config-error-msg span";
var esa = $("input#afw-esa").val();
var enterpriseId = $("input#afw-enterprise-id").val();
// KIOSK configs
var adminComponentName = $("input#android-kiosk-config-admin-component").val();
@ -289,6 +312,18 @@ $(document).ready(function () {
"contentType": "text"
};
var esa = {
"name": "esa",
"value": esa,
"contentType": "text"
};
var enterpriseId = {
"name": "enterpriseId",
"value": enterpriseId,
"contentType": "text"
};
var kioskDefaultOwner = {
"name": kioskConfigs["defaultOwnership"],
"value": defaultOwner,
@ -312,6 +347,8 @@ $(document).ready(function () {
configList.push(kioskWifiSSID);
configList.push(kioskWifiPassword);
configList.push(kioskWifiSecurity);
configList.push(esa);
configList.push(enterpriseId);
configList.push(kioskDefaultOwner);
configList.push(kioskServerIp);
@ -341,8 +378,136 @@ $(document).ready(function () {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
$(window).scrollTop(0);
}
);
}
});
});
function getSignupUrl(serverUrl, emmToken) {
var appContext = window.location.href;// mgt:9443 call to jaggery API
var tokenURL = appContext.replace("platform-configuration", "api/enterprise/token");
var callbackURL = appContext.replace("platform-configuration", "api/enterprise/enroll-complete");
var requestData = {};
requestData.externalToken = emmToken;
requestData.endpoint = serverUrl + "/api/android-for-work/v1.0/google/enterprise/signup-url";
requestData.callbackURL = callbackURL;
$.ajax({
type: "POST",
url: tokenURL,
data: JSON.stringify(requestData),
contentType: "application/json",
success: function(response) {
window.location.replace(response.signupURL);
},
error: function(data) {
var errorMsgWrapper = "#android-config-error-msg";
var errorMsg = "#android-config-error-msg span";
if (data.status == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data.status == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
$(window).scrollTop(0);
},
dataType: 'json'
});
}
$("button#afw-configure").click(function() {
var serverDetails = $("input#afw-server-details").val();
var emmToken = $("input#afw-backend-token").val();
getSignupUrl(serverDetails, emmToken)
});
var modalPopup = ".modal";
var modalPopupContainer = modalPopup + " .modal-content";
var modalPopupContent = modalPopup + " .modal-content";
var body = "body";
function unenroll(serverUrl, emmToken) {
var appContext = window.location.href;
var unenrollURL = appContext.replace("platform-configuration", "api/enterprise/unenroll");
var requestData = {};
requestData.externalToken = emmToken;
requestData.endpoint = serverUrl;
$.ajax({
type: "PUT",
url: unenrollURL,
data: JSON.stringify(requestData),
contentType: "application/json",
success: function(response) {
$("input#afw-server-details").val("") ;
$("input#afw-backend-token").val("");
$("input#afw-esa").val("");
$("input#afw-enterprise-id").val("");
},
error: function(data) {
var errorMsgWrapper = "#android-config-error-msg";
var errorMsg = "#android-config-error-msg span";
if (data.status == 200) {
$(errorMsg).text("hari.");
}
else if (data.status == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data.status == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
$(window).scrollTop(0);
},
dataType: 'text'
});
}
$("button#afw-unenroll").click(function() {
$(modalPopupContent).html($('#remove-unenroll-modal-content').html());
showPopup();
$("a#remove-unenroll-yes-link").click(function () {
var serverDetails = $("input#afw-server-details").val() + "/api/device-mgt/android/v1.0/enterprise/324/unenroll";
var emmToken = $("input#afw-backend-token").val();
unenroll(serverDetails, emmToken);
hidePopup();
});
$("a#remove-unenroll-cancel-link").click(function () {
hidePopup();
});
});
/*
* show popup function.
*/
function showPopup() {
$(modalPopup).modal('show');
}
/*
* hide popup function.
*/
function hidePopup() {
$(modalPopupContent).html("");
$(modalPopupContent).removeClass("operation-data");
$(modalPopup).modal('hide');
$('body').removeClass('modal-open').css('padding-right', '0px');
$('.modal-backdrop').remove();
}
});

@ -151,6 +151,122 @@ var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
var enrollmentAppInstallClick = function (input) {
if (input.checked) {
$("div#install-app-enrollment").find("input").filterByData("child-key", "installGooglePolicy").filterByData
("app-id",
input.getAttribute("data-app-id")).parent().parents("tr").last().find("input").each(function () {
if(!$(this).hasClass("child-input")) {
$(this).addClass("child-input");
}
});
} else {
var isInstallPolicyChecked = $("div#install-app-enrollment").find("input")
.filterByData("app-id", input.getAttribute("data-app-id"))
.filterByData("child-key", "installGooglePolicy").prop('checked');
if (!isInstallPolicyChecked) {
$("div#install-app-enrollment").find("input").filterByData("child-key", "installGooglePolicy").filterByData("app-id",
input.getAttribute("data-app-id")).parent().parents("tr").last().find
("input").each(function () {
$(this).removeClass("child-input");
});
}
}
};
var appAvailabilityClick = function (input) {
var appAvailabilityConfigFormTitle = document.getElementById("app-availability-config-form-title");
var isEnrollmentAppTicked = $("div#install-app-enrollment").find("input").filterByData("child-key",
"enrollmentAppInstall").filterByData("app-id", input.getAttribute("data-app-id")).prop('checked');
if (input.checked) {
var configureAppAvailabilityFormData = {};
configureAppAvailabilityFormData.autoInstallMode = "autoInstallOnce";
configureAppAvailabilityFormData.autoInstallPriority = "50";
configureAppAvailabilityFormData.chargingStateConstraint = "chargingNotRequired";
configureAppAvailabilityFormData.deviceIdleStateConstraint = "deviceIdleNotRequired";
configureAppAvailabilityFormData.networkTypeConstraint = "anyNetwork";
configureAppAvailabilityForm(configureAppAvailabilityFormData);
var title = "Add Configurations for " + input.getAttribute("data-app-name");
appAvailabilityConfigFormTitle.innerHTML = title;
$("input#app-install-config-save").attr("data-app-id", input.getAttribute("data-app-id"));
$("input#app-install-config-save").attr("data-package-name", input.getAttribute("data-package-name"));
$("div#app-availability-config-form").attr("hidden", false);
} else {
$("input#app-install-config-save").attr("data-app-id", "");
$("input#app-install-config-save").attr("data-package-name", "");
$("div#app-availability-config-form").attr("hidden", true);
if (!isEnrollmentAppTicked) {
// Enrollment app install tick is also not present. Meaning this row is not needed.
$("div#install-app-enrollment").find("input").filterByData("child-key",
"enrollmentAppInstall").filterByData("app-id", input
.getAttribute("data-app-id")).parent().parents("tr")
.last().find("input").each(function () {
$(this).removeClass("child-input");
});
}
}
};
var configureAppAvailabilityForm = function (input) {
$("select#app-availability-auto-install-mode").val(input.autoInstallMode).change();
$("select#app-availability-install-priority").val(input.autoInstallPriority).change();
$("select#app-availability-install-charging").val(input.chargingStateConstraint).change();
$("select#app-availability-install-idle").val(input.deviceIdleStateConstraint).change();
$("select#app-availability-install-network").val(input.networkTypeConstraint).change();
};
loadedGooglePolicyCount = 0;
var changeSavedGlobalAppConfig = function (input) {
// Adding this console log as, it is not possible to access the JS files otherwise.
console.log("This is printing from android-policy-*,js that is in accessible via source.");
$("div#install-app-enrollment").find("input").filterByData("child-key", "productSetBehavior")
.each(function () {
$(this).val($("select#product-set-behaviour").val());
});
$("div#install-app-enrollment").find("input").filterByData("child-key", "autoUpdatePolicy")
.each(function () {
$(this).val($("select#auto-update-policy").val());
});
var behaviour = $('select#product-set-behaviour').data('product-set-behavior');
var autoUpdatePolicy = $('select#auto-update-policy').data('auto-update-policy');
loadedGooglePolicyCount++;
if (autoUpdatePolicy && loadedGooglePolicyCount == 2) {
$("select#auto-update-policy").val(autoUpdatePolicy).change();
$("select#product-set-behaviour").val(behaviour).change()
}
};
var changeSavedAppInstallData = function (input) {
var appId = input.getAttribute("data-app-id");
var packageName = input.getAttribute("data-package-name")
var json = {};
json.appId = appId;
json.packageName = packageName;
json.autoInstallMode = $("select#app-availability-auto-install-mode").val();
json.autoInstallPriority = $("select#app-availability-install-priority").val();
json.chargingStateConstraint = $("select#app-availability-install-charging").val();
json.deviceIdleStateConstraint = $("select#app-availability-install-idle").val();
json.networkTypeConstraint = $("select#app-availability-install-network").val();
var payload = JSON.stringify(json);
$("div#install-app-enrollment").find("input").filterByData("package-name", packageName).parent().find("input")[1].value = payload;
$("div#install-app-enrollment").find("input").filterByData("package-name", packageName).parent().parents("tr")
.last().find("input").each(function () {
$(this).addClass("child-input");
});
$("div#app-availability-config-form").attr("hidden", true);
};
var ovpnConfigUploaded = function () {
var ovpnFileInput = document.getElementById("ovpn-file");
if ('files' in ovpnFileInput) {
@ -1188,7 +1304,7 @@ var showHideHelpText = function (addFormContainer) {
var applyDataTable = function() {
$("#enrollment-app-install-table").datatables_extended({
ordering: false,
lengthMenu: [5, 10, 25, 50, 100]
lengthMenu: [100, 200, 500]
});
};
var myFrom;
@ -1387,22 +1503,4 @@ $(document).ready(function () {
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
// add app entry for enrollment-app-install
$(advanceOperations).on("click", "[data-click-event=add-enrollment-app]", function () {
$(this).attr("hidden", true);
$(this).siblings("a").removeAttr("hidden");
$(this).parent().parent().find("input").each(function () {
$(this).addClass("child-input");
});
});
// remove app entry for enrollment-app-install
$(advanceOperations).on("click", "[data-click-event=remove-enrollment-app]", function () {
$(this).attr("hidden", true);
$(this).siblings("a").removeAttr("hidden");
$(this).parent().parent().find("input").each(function () {
$(this).removeClass("child-input");
});
});
});

@ -315,6 +315,146 @@
<option value="10">10</option>
</select>
</div>
<!--Passcode policy for work profile only-->
<h2 class="sub-title panel-title">Passcode policy for work profile</h2>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-exist" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyWPExist"
onchange="changeDivVisibility('wp-passcode-policy', this)"/>
<span class="helper" title="Enabled work profile passcode">
Enabled work profile passcode
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div id="wp-passcode-policy" style="display: none;">
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-allow-simple" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyAllowSimpleWP"
checked="checked"/>
<span class="helper"
title="Permits repeating, ascending and descending character sequences">
Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-require-alphanumeric" type="checkbox"
class="form-control operationDataKeys"
data-key="passcodePolicyRequireAlphanumericWP" checked="checked"/>
<span class="helper" title="Mandates to contain both letters and numbers">
Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-min-length" class="form-control operationDataKeys"
data-key="passcodePolicyMinLengthWP" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper"
title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-min-complex-chars" class="form-control operationDataKeys"
data-key="passcodePolicyMinComplexCharsWP" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days*
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or 0 for none )
</label>
<input id="wp-passcode-policy-max-passcode-age-in-days" type="text"
class="form-control operationDataKeys"
data-key="passcodePolicyMaxPasscodeAgeInDaysWP" maxlength="3">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-passcode-history">
Passcode history*
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or 0 for none )
</label>
<input id="wp-passcode-policy-passcode-history" type="text" class="form-control operationDataKeys"
data-key="passcodePolicyPasscodeHistoryWP" maxlength="2">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-max-failed-attempts">
Maximum number of failed attempts
<span class="helper"
title="The maximum number of incorrect password entries allowed. If the correct password is not entered within the allowed number of attempts, the data on the device will be erased.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-max-failed-attempts" class="form-control operationDataKeys"
data-key="passcodePolicyMaxFailedAttemptsWP" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</div>
</div>
</div>
@ -2973,14 +3113,15 @@
<div id="install-app-enrollment"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array specific-enrollment-app-install"
data-key="enrollmentAppInstall" data-column-count="5">
data-key="enrollmentAppInstall" data-column-count="11">
<table class="table table-responsive table-striped data-table" id="enrollment-app-install-table">
<thead>
<tr class="sort-row">
<th>Application Name</th>
<th>Type</th>
<th>Version</th>
<th></th>
<th>Auto Install</th>
<th>Work Profile Availability</th>
</tr>
</thead>
<tbody>
@ -3001,16 +3142,29 @@
<td data-title="enrollment-app-install-app-selection">
<input class="enrollment-app-install-input" type="hidden" data-child-key="uuid" value="{{this.uuid}}"/>
<input class="enrollment-app-install-input" type="hidden" data-child-key="appId" value="{{this.appId}}"/>
<a href="#enrollment-app-install-grid" data-click-event="add-enrollment-app">
<span>
<i class="fa fa-plus-circle fa-2x"></i>
</span>
</a>
<a href="#enrollment-app-install-grid" data-click-event="remove-enrollment-app" hidden>
<span>
<i class="fa fa-minus-circle fa-2x"></i>
</span>
</a>
<input class="enrollment-app-install-input" type="checkbox"
data-app-id="{{this.appId}}"
data-child-key="enrollmentAppInstall" onclick="enrollmentAppInstallClick (this)"
data-enrollment-app-install="{{this.enrollmentAppInstall}}" />
<input class="enrollment-app-install-input" type="hidden" data-child-key="packageName" value="{{this.packageName}}"/>
<input class="enrollment-app-install-input" type="hidden"
data-product-set-behavior=""
data-child-key="productSetBehavior" value="{{this.productSetBehavior}}"/>
<input class="enrollment-app-install-input" type="hidden"
data-auto-update-policy=""
data-child-key="autoUpdatePolicy" value="{{this.autoUpdatePolicy}}"/>
</td>
<td data-title="enrollment-app-install-app-configurations">
<input class="enrollment-app-install-input" type="checkbox"
onclick="appAvailabilityClick(this)"
data-app-id="{{this.appId}}"
data-app-name="{{this.appName}}" data-child-key="installGooglePolicy"
value="{{this.installGooglePolicy}}"
data-package-name="{{this.packageName}}" />
<input class="enrollment-app-install-input" type="hidden"
value="{{this.installGooglePolicyPayload}}"
data-app-id="{{this.appId}}"
data-child-key="installGooglePolicyPayload" />
</td>
</tr>
{{else}}
@ -3019,10 +3173,146 @@
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{{/each}}
</tbody>
</table>
<div id="app-availability-config-form" hidden="true">
<br><br>
<h2 class="sub-title"> App Install Policy(Work profile only)</h2>
<h2 id="app-availability-config-form-title" class="sub-title panel-title"></h2>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-auto-install-mode">
App Initial Install Mode
<span class="helper" title="The auto install mode for the first time">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-auto-install-mode" class="form-control operationDataKeys"
data-key="autoInstallMode" data-default="0">
<option value="autoInstallOnce" selected="selected">
Auto install once only when enrolling
</option>
<option value="doNotAutoInstall">Do not install automatically</option>
<option value="forceAutoInstall">Auto install even if uninstalled manually</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-priority">
Priority level when installing the app
<span class="helper" title="Priority level when installing the app among many other apps">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-priority" class="form-control operationDataKeys"
data-key="autoInstallPriority" data-default="0">
<option value="10">
Highest
</option>
<option value="20">High</option>
<option value="30">Medium</option>
<option value="40">Low</option>
<option value="50">Lowest</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-charging">
Device charging state when installing apps
<span class="helper" title="Device charging state when installing apps">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-charging" class="form-control operationDataKeys"
data-key="chargingStateConstraint" data-default="0">
<option value="chargingRequired">Device must be charging</option>
<option value="chargingNotRequired">Device does not need to be charging</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-idle">
Device processor state when installing
<span class="helper" title="Device processor state when installing">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-idle" class="form-control operationDataKeys"
data-key="deviceIdleStateConstraint" data-default="0">
<option value="deviceIdleNotRequired">
Device does not need to be idling
</option>
<option value="deviceIdleRequired">Device must be idling</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-network">
Device network state when installing
<span class="helper" title="Device processor state when installing">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-network" class="form-control operationDataKeys"
data-key="networkTypeConstraint" data-default="0">
<option value="anyNetwork">
Device can be in any network
</option>
<option value="unmeteredNetwork">Device must be in an unmetered network</option>
</select>
</div>
<input class="wr-btn wizard-stepper" type="button" value="Save" id="app-install-config-save"
onclick="changeSavedAppInstallData(this)" data-app-id="" data-package-name=""/>
</div>
</div>
<div id="app-availability-global-config-form">
<br><br>
<h2 class="sub-title">Work profile global user configurations</h2>
<div class="wr-input-control">
<label class="wr-input-label" for="auto-update-policy">
App Auto Update Policy
<span class="helper" title="The auto-update policy for apps installed on the device">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="auto-update-policy" class="form-control operationDataKeys"
data-key="autoUpdatePolicy" data-default="0" onchange="changeSavedGlobalAppConfig(this)">
<option value="wifiOnly">
When connected to WiFi
</option>
<option value="always">Auto Update Anytime</option>
<option value="choiceToTheUser">Ask User To Update</option>
<option value="never">Disable Auto Update</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="product-set-behaviour">
App Availability To A User
<span class="helper" title="The availability granted to the user for the specified app">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="product-set-behaviour" class="form-control operationDataKeys"
data-key="productSetBehavior" data-default="0" onchange="changeSavedGlobalAppConfig(this)">
<option value="allApproved">All Approved Apps For Enterprise</option>
<option value="includeAll">All Apps From Playstore</option>
<option value="whitelist">Only Whitelisted Apps</option>productAvailabilityPolicy
</select>
</div>
</div>
</div>
</div>
@ -3030,4 +3320,4 @@
<!--/enrolment-app-install-->
</div>
<script type="text/javascript">applyDataTable();</script>
</div>
</div>

@ -297,6 +297,144 @@
<option value="10">10</option>
</select>
</div>
<!--Passcode policy for work profile only-->
<h2 class="sub-title panel-title">Passcode policy for work profile</h2>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-exist" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyWPExist"
onchange="changeDivVisibility('wp-passcode-policy', this)"/>
<span class="helper" title="Enabled work profile passcode" disabled>
Enabled work profile passcode
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div id="wp-passcode-policy" style="display: none;">
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-allow-simple" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyAllowSimpleWP"
checked="checked" disabled/>
<span class="helper"
title="Permits repeating, ascending and descending character sequences">
Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-require-alphanumeric" type="checkbox"
class="form-control operationDataKeys"
data-key="passcodePolicyRequireAlphanumericWP" checked="checked" disabled/>
<span class="helper" title="Mandates to contain both letters and numbers">
Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-min-length" class="form-control operationDataKeys"
data-key="passcodePolicyMinLengthWP" data-default="0" disabled>
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper"
title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-min-complex-chars" class="form-control operationDataKeys"
data-key="passcodePolicyMinComplexCharsWP" data-default="0" disabled>
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days*
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or 0 for none )
</label>
<input id="wp-passcode-policy-max-passcode-age-in-days" type="text"
class="form-control operationDataKeys"
data-key="passcodePolicyMaxPasscodeAgeInDaysWP" maxlength="3" disabled>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-passcode-history">
Passcode history*
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or 0 for none )
</label>
<input id="wp-passcode-policy-passcode-history" type="text" class="form-control operationDataKeys"
data-key="passcodePolicyPasscodeHistoryWP" maxlength="2" disabled>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-max-failed-attempts">
Maximum number of failed attempts
<span class="helper"
title="The maximum number of incorrect password entries allowed. If the correct password is not entered within the allowed number of attempts, the data on the device will be erased.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-max-failed-attempts" class="form-control operationDataKeys"
data-key="passcodePolicyMaxFailedAttemptsWP" data-default="0" disabled>
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</div>
</div>
@ -3083,6 +3221,8 @@
<th>Application Name</th>
<th>Type</th>
<th>Version</th>
<th>Auto Install</th>
<th>Work Profile Availability</th>
</tr>
</thead>
<tbody data-add-form-container="#enrollment-app-install-grid">

@ -93,6 +93,122 @@ var inputIsValidAgainstRange = function (numberInput, min, max) {
return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max);
};
var enrollmentAppInstallClick = function (input) {
if (input.checked) {
$("div#install-app-enrollment").find("input").filterByData("child-key", "installGooglePolicy").filterByData
("app-id",
input.getAttribute("data-app-id")).parent().parents("tr").last().find("input").each(function () {
if(!$(this).hasClass("child-input")) {
$(this).addClass("child-input");
}
});
} else {
var isInstallPolicyChecked = $("div#install-app-enrollment").find("input")
.filterByData("app-id", input.getAttribute("data-app-id"))
.filterByData("child-key", "installGooglePolicy").prop('checked');
if (!isInstallPolicyChecked) {
$("div#install-app-enrollment").find("input").filterByData("child-key", "installGooglePolicy").filterByData("app-id",
input.getAttribute("data-app-id")).parent().parents("tr").last().find
("input").each(function () {
$(this).removeClass("child-input");
});
}
}
};
var appAvailabilityClick = function (input) {
var appAvailabilityConfigFormTitle = document.getElementById("app-availability-config-form-title");
var isEnrollmentAppTicked = $("div#install-app-enrollment").find("input").filterByData("child-key",
"enrollmentAppInstall").filterByData("app-id", input.getAttribute("data-app-id")).prop('checked');
if (input.checked) {
var configureAppAvailabilityFormData = {};
configureAppAvailabilityFormData.autoInstallMode = "autoInstallOnce";
configureAppAvailabilityFormData.autoInstallPriority = "50";
configureAppAvailabilityFormData.chargingStateConstraint = "chargingNotRequired";
configureAppAvailabilityFormData.deviceIdleStateConstraint = "deviceIdleNotRequired";
configureAppAvailabilityFormData.networkTypeConstraint = "anyNetwork";
configureAppAvailabilityForm(configureAppAvailabilityFormData);
var title = "Add Configurations for " + input.getAttribute("data-app-name");
appAvailabilityConfigFormTitle.innerHTML = title;
$("input#app-install-config-save").attr("data-app-id", input.getAttribute("data-app-id"));
$("input#app-install-config-save").attr("data-package-name", input.getAttribute("data-package-name"));
$("div#app-availability-config-form").attr("hidden", false);
$("div#install-app-enrollment").find("input").filterByData("child-key", "productSetBehavior").each(function () {
if (!$(this).val()) {
$(this).val("whitelist");
}
});
$("div#install-app-enrollment").find("input").filterByData("child-key", "autoUpdatePolicy").each(function () {
if (!$(this).val()) {
$(this).val("wifiOnly");
}
});
} else {
$("input#app-install-config-save").attr("data-app-id", "");
$("input#app-install-config-save").attr("data-package-name", "");
$("div#app-availability-config-form").attr("hidden", true);
if (!isEnrollmentAppTicked) {
// Enrollment app install tick is also not present. Meaning this row is not needed.
$("div#install-app-enrollment").find("input").filterByData("child-key",
"enrollmentAppInstall").filterByData("app-id", input
.getAttribute("data-app-id")).parent().parents("tr")
.last().find("input").each(function () {
$(this).removeClass("child-input");
});
}
}
};
var configureAppAvailabilityForm = function (input) {
$("select#app-availability-auto-install-mode").val(input.autoInstallMode).change();
$("select#app-availability-install-priority").val(input.autoInstallPriority).change();
$("select#app-availability-install-charging").val(input.chargingStateConstraint).change();
$("select#app-availability-install-idle").val(input.deviceIdleStateConstraint).change();
$("select#app-availability-install-network").val(input.networkTypeConstraint).change();
};
var changeSavedGlobalAppConfig = function (input) {
$("div#install-app-enrollment").find("input").filterByData("child-key", "productSetBehavior")
.each(function () {
$(this).val($("select#product-set-behaviour").val());
});
$("div#install-app-enrollment").find("input").filterByData("child-key", "autoUpdatePolicy")
.each(function () {
$(this).val($("select#auto-update-policy").val());
});
};
var changeSavedAppInstallData = function (input) {
var appId = input.getAttribute("data-app-id");
var packageName = input.getAttribute("data-package-name")
var json = {};
json.appId = appId;
json.packageName = packageName;
json.autoInstallMode = $("select#app-availability-auto-install-mode").val();
json.autoInstallPriority = $("select#app-availability-install-priority").val();
json.chargingStateConstraint = $("select#app-availability-install-charging").val();
json.deviceIdleStateConstraint = $("select#app-availability-install-idle").val();
json.networkTypeConstraint = $("select#app-availability-install-network").val();
var payload = JSON.stringify(json);
$("div#install-app-enrollment").find("input").filterByData("package-name", packageName).parent().find("input")[1].value = payload;
$("div#install-app-enrollment").find("input").filterByData("package-name", packageName).parent().parents("tr")
.last().find("input").each(function () {
$(this).addClass("child-input");
});
$("div#app-availability-config-form").attr("hidden", true);
};
var ovpnConfigUploaded = function () {
var ovpnFileInput = document.getElementById("ovpn-file");
if ('files' in ovpnFileInput) {
@ -1163,7 +1279,7 @@ var showHideHelpText = function (addFormContainer) {
var applyDataTable = function() {
$("#enrollment-app-install-table").datatables_extended({
ordering: false,
lengthMenu: [5, 10, 25, 50, 100]
lengthMenu: [100, 200, 500]
});
};
@ -1344,22 +1460,4 @@ $(document).ready(function () {
setId(addFormContainer);
showHideHelpText(addFormContainer);
});
// add app entry for enrollment-app-install
$(advanceOperations).on("click", "[data-click-event=add-enrollment-app]", function () {
$(this).attr("hidden", true);
$(this).siblings("a").removeAttr("hidden");
$(this).parent().parent().find("input").each(function () {
$(this).addClass("child-input");
});
});
// remove app entry for enrollment-app-install
$(advanceOperations).on("click", "[data-click-event=remove-enrollment-app]", function () {
$(this).attr("hidden", true);
$(this).siblings("a").removeAttr("hidden");
$(this).parent().parent().find("input").each(function () {
$(this).removeClass("child-input");
});
});
});

@ -323,9 +323,150 @@
<option value="10">10</option>
</select>
</div>
<!--Passcode policy for work profile only-->
<h2 class="sub-title panel-title">Passcode policy for work profile</h2>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-exist" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyWPExist"
onchange="changeDivVisibility('wp-passcode-policy', this)"/>
<span class="helper" title="Enabled work profile passcode">
Enabled work profile passcode
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div id="wp-passcode-policy" style="display: none;">
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-allow-simple" type="checkbox"
class="form-control operationDataKeys" data-key="passcodePolicyAllowSimpleWP"
checked="checked"/>
<span class="helper"
title="Permits repeating, ascending and descending character sequences">
Allow simple value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="wp-passcode-policy-require-alphanumeric" type="checkbox"
class="form-control operationDataKeys"
data-key="passcodePolicyRequireAlphanumericWP" checked="checked"/>
<span class="helper" title="Mandates to contain both letters and numbers">
Require alphanumeric value
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-min-length">
Minimum passcode length
<span class="helper" title="Minimum number of characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-min-length" class="form-control operationDataKeys"
data-key="passcodePolicyMinLengthWP" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-min-complex-chars">
Minimum number of complex characters
<span class="helper"
title="Minimum number of complex or non-alphanumeric characters allowed in a passcode">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-min-complex-chars" class="form-control operationDataKeys"
data-key="passcodePolicyMinComplexCharsWP" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="1">01</option>
<option value="2">02</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-max-passcode-age-in-days">
Maximum passcode age in days*
<span class="helper" title="Number of days after which a passcode must be changed">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-730 days or 0 for none )
</label>
<input id="wp-passcode-policy-max-passcode-age-in-days" type="text"
class="form-control operationDataKeys"
data-key="passcodePolicyMaxPasscodeAgeInDaysWP" maxlength="3">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-passcode-history">
Passcode history*
<span class="helper" title="Number of consequent unique passcodes to be used before reuse">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
( Should be in between 1-to-50 passcodes or 0 for none )
</label>
<input id="wp-passcode-policy-passcode-history" type="text" class="form-control operationDataKeys"
data-key="passcodePolicyPasscodeHistoryWP" maxlength="2">
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="wp-passcode-policy-max-failed-attempts">
Maximum number of failed attempts
<span class="helper"
title="The maximum number of incorrect password entries allowed. If the correct password is not entered within the allowed number of attempts, the data on the device will be erased.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="wp-passcode-policy-max-failed-attempts" class="form-control operationDataKeys"
data-key="passcodePolicyMaxFailedAttemptsWP" data-default="0">
<option value="" selected="selected">
None
</option>
<option value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>
<option value="9">09</option>
<option value="10">10</option>
</select>
</div>
</div>
</div>
</div>
</div>
<!-- /passcode-policy -->
<!-- camera -->
<div class="wr-hidden-operation" data-operation="camera">
<div class="panel panel-default operation-data" data-operation="camera" data-operation-code="CAMERA">
@ -2959,6 +3100,7 @@
</div>
</div>
<!--enrolment-app-install-->
<div class="wr-hidden-operation" data-operation="enrollment-app-install">
<div class="panel panel-default operation-data" data-operation="enrollment-app-install"
@ -2994,15 +3136,16 @@
<div id="install-app-enrollment"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array specific-enrollment-app-install"
data-key="enrollmentAppInstall" data-column-count="5">
data-key="enrollmentAppInstall" data-column-count="11">
<table class="table table-responsive table-striped data-table" id="enrollment-app-install-table">
<thead>
<tr class="sort-row">
<th>Application Name</th>
<th>Type</th>
<th>Version</th>
<th></th>
</tr>
<tr class="sort-row">
<th>Application Name</th>
<th>Type</th>
<th>Version</th>
<th>Auto Install</th>
<th>Work Profile Availability</th>
</tr>
</thead>
<tbody>
{{#each storeapps}}
@ -3015,23 +3158,32 @@
{{this.type}}
<input class="enrollment-app-install-input" type="hidden" data-child-key="type" value="{{this.type}}"/>
</td>
<td data-title="enrollment-app-install-app-version">
<td data-title="enrollment-app-install-app-name">
{{this.version}}
<input class="enrollment-app-install-input" type="hidden" data-child-key="version" value="{{this.version}}"/>
</td>
<td data-title="enrollment-app-install-app-selection">
<input class="enrollment-app-install-input" type="hidden" data-child-key="uuid" value="{{this.uuid}}"/>
<input class="enrollment-app-install-input" type="hidden" data-child-key="appId" value="{{this.appId}}"/>
<a href="#enrollment-app-install-grid" data-click-event="add-enrollment-app">
<span>
<i class="fa fa-plus-circle fa-2x"></i>
</span>
</a>
<a href="#enrollment-app-install-grid" data-click-event="remove-enrollment-app" hidden>
<span>
<i class="fa fa-minus-circle fa-2x"></i>
</span>
</a>
<input class="enrollment-app-install-input" type="checkbox"
data-app-id="{{this.appId}}"
data-child-key="enrollmentAppInstall" onclick="enrollmentAppInstallClick (this)"
data-enrollment-app-install="{{this.enrollmentAppInstall}}" />
<input class="enrollment-app-install-input" type="hidden" data-child-key="packageName" value="{{this.packageName}}"/>
<input class="enrollment-app-install-input" type="hidden" data-child-key="productSetBehavior" value="{{this.productSetBehavior}}"/>
<input class="enrollment-app-install-input" type="hidden" data-child-key="autoUpdatePolicy" value="{{this.autoUpdatePolicy}}"/>
</td>
<td data-title="enrollment-app-install-app-configurations">
<input class="enrollment-app-install-input" type="checkbox"
onclick="appAvailabilityClick(this)"
data-app-id="{{this.appId}}"
data-app-name="{{this.appName}}" data-child-key="installGooglePolicy"
value="{{this.installGooglePolicy}}"
data-package-name="{{this.packageName}}" />
<input class="enrollment-app-install-input" type="hidden"
value="{{this.installGooglePolicyPayload}}"
data-app-id="{{this.appId}}"
data-child-key="installGooglePolicyPayload" />
</td>
</tr>
{{else}}
@ -3040,10 +3192,144 @@
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{{/each}}
</tbody>
</table>
<div id="app-availability-config-form" hidden="true">
<br><br>
<h2 class="sub-title"> App Install Policy(Work profile only)</h2>
<h2 id="app-availability-config-form-title" class="sub-title panel-title"></h2>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-auto-install-mode">
App Initial Install Mode
<span class="helper" title="The auto install mode for the first time">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-auto-install-mode" class="form-control operationDataKeys"
data-key="autoInstallMode" data-default="0">
<option value="autoInstallOnce">
Auto install once only when enrolling
</option>
<option value="doNotAutoInstall">Do not install automatically</option>
<option value="forceAutoInstall">Auto install even if uninstalled manually</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-priority">
Priority level when installing the app
<span class="helper" title="Priority level when installing the app among many other apps">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-priority" class="form-control operationDataKeys"
data-key="autoInstallPriority" data-default="0">
<option value="10">
Highest
</option>
<option value="20">High</option>
<option value="30">Medium</option>
<option value="40">Low</option>
<option value="50">Lowest</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-charging">
Device charging state when installing apps
<span class="helper" title="Device charging state when installing apps">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-charging" class="form-control operationDataKeys"
data-key="chargingStateConstraint" data-default="0">
<option value="chargingRequired">Device must be charging</option>
<option value="chargingNotRequired">Device does not need to be charging</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-idle">
Device processor state when installing
<span class="helper" title="Device processor state when installing">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-idle" class="form-control operationDataKeys"
data-key="deviceIdleStateConstraint" data-default="0">
<option value="deviceIdleNotRequired">
Device does not need to be idling
</option>
<option value="deviceIdleRequired">Device must be idling</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="app-availability-install-network">
Device network state when installing
<span class="helper" title="Device processor state when installing">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="app-availability-install-network" class="form-control operationDataKeys"
data-key="networkTypeConstraint" data-default="0">
<option value="anyNetwork">
Device can be in any network
</option>
<option value="unmeteredNetwork">Device must be in an unmetered network</option>
</select>
</div>
<input class="wr-btn wizard-stepper" type="button" value="Save" id="app-install-config-save"
onclick="changeSavedAppInstallData(this)" data-app-id="" data-package-name=""/>
</div>
</div>
<div id="app-availability-global-config-form">
<br><br>
<h2 class="sub-title">Work profile global user configurations</h2>
<div class="wr-input-control">
<label class="wr-input-label" for="auto-update-policy">
App Auto Update Policy
<span class="helper" title="The auto-update policy for apps installed on the device">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="auto-update-policy" class="form-control operationDataKeys"
data-key="autoUpdatePolicy" data-default="0" onchange="changeSavedGlobalAppConfig(this)">
<option value="wifiOnly">
When connected to WiFi
</option>
<option value="always">Auto Update Anytime</option>
<option value="choiceToTheUser">Ask User To Update</option>
<option value="never">Disable Auto Update</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="product-set-behaviour">
App Availability To A User
<span class="helper" title="The availability granted to the user for the specified app">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<select id="product-set-behaviour" class="form-control operationDataKeys"
data-key="productSetBehavior" data-default="0" onchange="changeSavedGlobalAppConfig(this)">
<option value="allApproved">All Approved Apps For Enterprise</option>
<option value="includeAll">All Apps From Playstore</option>
<option value="whitelist">Only Whitelisted Apps</option>productAvailabilityPolicy
</select>
</div>
</div>
</div>
</div>

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /*
~ * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~ *
~ * WSO2 Inc. licenses this file to you under the Apache License,
~ * Version 2.0 (the "License"); you may not use this file except
~ * in compliance with the License.
~ * You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing,
~ * software distributed under the License is distributed on an
~ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ * KIND, either express or implied. See the License for the
~ * specific language governing permissions and limitations
~ * under the License.
~ */
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<jaxrs:server id="services" address="/">
<jaxrs:serviceBeans>
<ref bean="deviceManagementService"/>
<ref bean="deviceManagementAdminService"/>
<ref bean="eventReceiverService"/>
<ref bean="androidEnterprise"/>
<ref bean="deviceTypeConfigurationService"/>
<ref bean="swaggerResource"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jsonProvider"/>
<ref bean="errorHandler"/>
<ref bean="swaggerWriter"/>
<ref bean="GlobalExceptionMapper"/>
</jaxrs:providers>
<jaxrs:properties>
<!-- This is added to catch interceptor level exceptions in GlobalThrowableMapper. -->
<entry key="map.cxf.interceptor.fault" value="true" />
</jaxrs:properties>
</jaxrs:server>
<bean id="swaggerWriter" class="io.swagger.jaxrs.listing.SwaggerSerializers" />
<bean id="swaggerResource" class="io.swagger.jaxrs.listing.ApiListingResource" />
<bean id="GlobalExceptionMapper" class="org.wso2.carbon.mdm.services.android.exception.GlobalThrowableMapper"/>
<bean id="ValidationInterceptor" class="org.wso2.carbon.mdm.services.android.common.ValidationInterceptor"/>
<bean id="swaggerConfig" class="io.swagger.jaxrs.config.BeanConfig">
<property name="resourcePackage" value="org.wso2.carbon.mdm.services.android.services"/>
<property name="version" value="0.9"/>
<property name="host" value="localhost:9443"/>
<property name="schemes" value="https" />
<property name="basePath" value="/api/device-mgt/android/v0.9"/>
<property name="title" value="Android Device Management API Definitions"/>
<property name="contact" value="dev@wso2.org"/>
<property name="license" value="Apache 2.0"/>
<property name="licenseUrl" value="http://www.apache.org/licenses/LICENSE-2.0.html"/>
<property name="scan" value="true"/>
</bean>
<bean id="deviceManagementService" class="org.wso2.carbon.mdm.services.android.services.impl.DeviceManagementServiceImpl"/>
<bean id="deviceManagementAdminService" class="org.wso2.carbon.mdm.services.android.services.impl.DeviceManagementAdminServiceImpl"/>
<bean id="eventReceiverService" class="org.wso2.carbon.mdm.services.android.services.impl.EventReceiverServiceImpl"/>
<bean id="deviceTypeConfigurationService" class="org.wso2.carbon.mdm.services.android.services.impl.DeviceTypeConfigurationServiceImpl"/>
<bean id="androidEnterprise" class="org.wso2.carbon.mdm.services.android.services.impl.AndroidEnterpriseServiceImpl"/>
<bean id="jsonProvider" class="org.wso2.carbon.mdm.services.android.common.GsonMessageBodyHandler"/>
<bean id="errorHandler" class="org.wso2.carbon.mdm.services.android.common.ErrorHandler"/>
<cxf:bus>
<cxf:inInterceptors>
<ref bean="ValidationInterceptor"/>
</cxf:inInterceptors>
</cxf:bus>
</beans>

@ -0,0 +1,42 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android;
import org.wso2.carbon.device.mgt.mobile.android.impl.EnterpriseServiceException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseManagedConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import java.util.List;
public interface AndroidPluginService {
void addEnterpriseUser(AndroidEnterpriseUser androidEnterpriseUser) throws EnterpriseServiceException;
List<AndroidEnterpriseUser> getEnterpriseUser(String username) throws EnterpriseServiceException;
AndroidEnterpriseUser getEnterpriseUserByDevice(String deviceId) throws EnterpriseServiceException;
AndroidEnterpriseManagedConfig getConfigByPackageName(String packageName) throws EnterpriseServiceException;
void addConfig(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseServiceException;
boolean updateMobileDevice(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseServiceException;
boolean deleteMobileDevice(String id) throws EnterpriseServiceException;
}

@ -84,8 +84,7 @@ public class AndroidDeviceManagementService implements DeviceManagementService {
@Override
public void init() throws DeviceManagementException {
this.deviceManager = new AndroidDeviceManager();
this.policyMonitoringManager = new AndroidPolicyMonitoringManager();
}
@Override
@ -105,29 +104,6 @@ public class AndroidDeviceManagementService implements DeviceManagementService {
@Override
public PushNotificationConfig getPushNotificationConfig() {
try {
DeviceManagementService deviceManagementService = AndroidDeviceManagementDataHolder.getInstance().
getAndroidDeviceManagementService();
if (deviceManagementService != null && deviceManagementService.getDeviceManager() != null) {
PlatformConfiguration androidConfig = deviceManagementService.getDeviceManager().getConfiguration();
if (androidConfig != null) {
List<ConfigurationEntry> configuration = androidConfig.getConfiguration();
String notifierValue = this.getConfigProperty(configuration, NOTIFIER_PROPERTY);
if (notifierValue != null && !notifierValue.isEmpty()) {
int notifierType = Integer.parseInt(notifierValue);
if (notifierType == 2) {
HashMap<String, String> config = new HashMap<>();
config.put(FCM_API_KEY, this.getConfigProperty(configuration, FCM_API_KEY));
config.put(FCM_SENDER_ID, this.getConfigProperty(configuration, FCM_SENDER_ID));
return new PushNotificationConfig(AndroidPluginConstants.NotifierType.FCM, false,
config);
}
}
}
}
} catch (DeviceManagementException e) {
log.error("Unable to get the Android platform configuration from registry.");
}
return null;
}

@ -1,381 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.mobile.android.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException;
import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager;
import org.wso2.carbon.device.mgt.extensions.license.mgt.registry.RegistryBasedLicenseManager;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AbstractMobileDeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl.AndroidDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileDevice;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginConstants;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginUtils;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.MobileDeviceManagementUtil;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
public class AndroidDeviceManager implements DeviceManager {
private AbstractMobileDeviceManagementDAOFactory daoFactory;
private static final Log log = LogFactory.getLog(AndroidDeviceManagementService.class);
private FeatureManager featureManager = new AndroidFeatureManager();
private LicenseManager licenseManager;
public AndroidDeviceManager() {
this.daoFactory = new AndroidDAOFactory();
this.licenseManager = new RegistryBasedLicenseManager();
License defaultLicense;
try {
if (licenseManager.getLicense(AndroidDeviceManagementService.DEVICE_TYPE_ANDROID,
AndroidPluginConstants.MobilePluginConstants.LANGUAGE_CODE_ENGLISH_US) ==
null) {
defaultLicense = AndroidPluginUtils.getDefaultLicense();
licenseManager.addLicense(AndroidDeviceManagementService.DEVICE_TYPE_ANDROID, defaultLicense);
}
featureManager.addSupportedFeaturesToDB();
} catch (LicenseManagementException e) {
log.error("Error occurred while adding default license for Android devices", e);
} catch (DeviceManagementException e) {
log.error("Error occurred while adding supported device features for Android platform", e);
}
}
@Override
public FeatureManager getFeatureManager() {
return featureManager;
}
@Override
public boolean saveConfiguration(PlatformConfiguration tenantConfiguration)
throws DeviceManagementException {
boolean status;
try {
if (log.isDebugEnabled()) {
log.debug("Persisting android configurations in Registry");
}
String resourcePath = MobileDeviceManagementUtil.getPlatformConfigPath(
DeviceManagementConstants.
MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(PlatformConfiguration.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(tenantConfiguration, writer);
Resource resource = MobileDeviceManagementUtil.getConfigurationRegistry().newResource();
resource.setContent(writer.toString());
resource.setMediaType(AndroidPluginConstants.MobilePluginConstants.MEDIA_TYPE_XML);
MobileDeviceManagementUtil.putRegistryResource(resourcePath, resource);
status = true;
} catch (AndroidDeviceMgtPluginException e) {
throw new DeviceManagementException(
"Error occurred while retrieving the Registry instance : " + e.getMessage(), e);
} catch (RegistryException e) {
throw new DeviceManagementException(
"Error occurred while persisting the Registry resource of Android Configuration : " + e.getMessage(), e);
} catch (JAXBException e) {
throw new DeviceManagementException(
"Error occurred while parsing the Android configuration : " + e.getMessage(), e);
}
return status;
}
@Override
public PlatformConfiguration getConfiguration() throws DeviceManagementException {
Resource resource;
try {
String androidRegPath =
MobileDeviceManagementUtil.getPlatformConfigPath(DeviceManagementConstants.
MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
resource = MobileDeviceManagementUtil.getRegistryResource(androidRegPath);
if (resource != null) {
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLStreamReader reader = factory.createXMLStreamReader(
new StringReader(new String((byte[]) resource.getContent(), Charset.
forName(AndroidPluginConstants.MobilePluginConstants.CHARSET_UTF8))));
JAXBContext context = JAXBContext.newInstance(PlatformConfiguration.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
return (PlatformConfiguration) unmarshaller.unmarshal(reader);
}
return null;
} catch (AndroidDeviceMgtPluginException e) {
throw new DeviceManagementException(
"Error occurred while retrieving the Registry instance : " + e.getMessage(), e);
} catch (JAXBException | XMLStreamException e) {
throw new DeviceManagementException(
"Error occurred while parsing the Android configuration : " + e.getMessage(), e);
} catch (RegistryException e) {
throw new DeviceManagementException(
"Error occurred while retrieving the Registry resource of Android Configuration : " + e.getMessage(), e);
}
}
@Override
public boolean enrollDevice(Device device) throws DeviceManagementException {
boolean status = false;
boolean isEnrolled = this.isEnrolled(
new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
try {
if (log.isDebugEnabled()) {
log.debug("Enrolling a new Android device : " + device.getDeviceIdentifier());
}
if (isEnrolled) {
this.modifyEnrollment(device);
} else {
MobileDevice mobileDevice = MobileDeviceManagementUtil.convertToMobileDevice(device);
AndroidDAOFactory.beginTransaction();
status = daoFactory.getMobileDeviceDAO().addMobileDevice(mobileDevice);
AndroidDAOFactory.commitTransaction();
}
} catch (MobileDeviceManagementDAOException e) {
try {
AndroidDAOFactory.rollbackTransaction();
} catch (MobileDeviceManagementDAOException mobileDAOEx) {
String msg = "Error occurred while roll back the device enrol transaction :" +
device.toString();
log.warn(msg, mobileDAOEx);
}
String msg =
"Error while enrolling the Android device : " + device.getDeviceIdentifier();
throw new DeviceManagementException(msg, e);
}
return status;
}
@Override
public boolean modifyEnrollment(Device device) throws DeviceManagementException {
boolean status;
MobileDevice mobileDevice = MobileDeviceManagementUtil.convertToMobileDevice(device);
try {
if (log.isDebugEnabled()) {
log.debug("Modifying the Android device enrollment data");
}
AndroidDAOFactory.beginTransaction();
status = daoFactory.getMobileDeviceDAO().updateMobileDevice(mobileDevice);
AndroidDAOFactory.commitTransaction();
} catch (MobileDeviceManagementDAOException e) {
try {
AndroidDAOFactory.rollbackTransaction();
} catch (MobileDeviceManagementDAOException mobileDAOEx) {
String msg = "Error occurred while roll back the update device transaction :" +
device.toString();
log.warn(msg, mobileDAOEx);
}
String msg = "Error while updating the enrollment of the Android device : " +
device.getDeviceIdentifier();
throw new DeviceManagementException(msg, e);
}
return status;
}
@Override
public boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException {
//Here we don't have anything specific to do. Hence returning.
return true;
}
@Override
public boolean isEnrolled(DeviceIdentifier deviceId) throws DeviceManagementException {
boolean isEnrolled = false;
try {
if (log.isDebugEnabled()) {
log.debug("Checking the enrollment of Android device : " + deviceId.getId());
}
MobileDevice mobileDevice =
daoFactory.getMobileDeviceDAO().getMobileDevice(deviceId.getId());
if (mobileDevice != null) {
isEnrolled = true;
}
} catch (MobileDeviceManagementDAOException e) {
String msg = "Error while checking the enrollment status of Android device : " +
deviceId.getId();
throw new DeviceManagementException(msg, e);
}
return isEnrolled;
}
@Override
public boolean isActive(DeviceIdentifier deviceId) throws DeviceManagementException {
return true;
}
@Override
public boolean setActive(DeviceIdentifier deviceId, boolean status)
throws DeviceManagementException {
return true;
}
@Override
public Device getDevice(DeviceIdentifier deviceId) throws DeviceManagementException {
Device device;
try {
if (log.isDebugEnabled()) {
log.debug("Getting the details of Android device : '" + deviceId.getId() + "'");
}
MobileDevice mobileDevice = daoFactory.getMobileDeviceDAO().
getMobileDevice(deviceId.getId());
device = MobileDeviceManagementUtil.convertToDevice(mobileDevice);
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException(
"Error occurred while fetching the Android device: '" +
deviceId.getId() + "'", e);
}
return device;
}
@Override
public boolean updateDeviceProperties(DeviceIdentifier deviceIdentifier, List<Device.Property> list) throws DeviceManagementException {
return false;
}
@Override
public boolean setOwnership(DeviceIdentifier deviceId, String ownershipType)
throws DeviceManagementException {
return true;
}
@Override
public boolean isClaimable(DeviceIdentifier deviceIdentifier) throws DeviceManagementException {
return false;
}
@Override
public boolean setStatus(DeviceIdentifier deviceIdentifier, String currentUser,
EnrolmentInfo.Status status) throws DeviceManagementException {
return false;
}
@Override
public License getLicense(String languageCode) throws LicenseManagementException {
return licenseManager.
getLicense(AndroidDeviceManagementService.DEVICE_TYPE_ANDROID, languageCode);
}
@Override
public void addLicense(License license) throws LicenseManagementException {
licenseManager.addLicense(AndroidDeviceManagementService.DEVICE_TYPE_ANDROID, license);
}
@Override
public boolean requireDeviceAuthorization() {
return true;
}
@Override
public boolean updateDeviceInfo(DeviceIdentifier deviceIdentifier, Device device)
throws DeviceManagementException {
boolean status;
Device existingDevice = this.getDevice(deviceIdentifier);
// This object holds the current persisted device object
MobileDevice existingMobileDevice =
MobileDeviceManagementUtil.convertToMobileDevice(existingDevice);
// This object holds the newly received device object from response
MobileDevice mobileDevice = MobileDeviceManagementUtil.convertToMobileDevice(device);
// Updating current object features using newer ones
existingMobileDevice.setLatitude(mobileDevice.getLatitude());
existingMobileDevice.setLongitude(mobileDevice.getLongitude());
existingMobileDevice.setAltitude(mobileDevice.getAltitude());
existingMobileDevice.setSpeed(mobileDevice.getSpeed());
existingMobileDevice.setBearing(mobileDevice.getBearing());
existingMobileDevice.setDistance(mobileDevice.getDistance());
existingMobileDevice.setDeviceProperties(mobileDevice.getDeviceProperties());
try {
if (log.isDebugEnabled()) {
log.debug(
"updating the details of Android device : " + device.getDeviceIdentifier());
}
AndroidDAOFactory.beginTransaction();
status = daoFactory.getMobileDeviceDAO().updateMobileDevice(existingMobileDevice);
AndroidDAOFactory.commitTransaction();
} catch (MobileDeviceManagementDAOException e) {
try {
AndroidDAOFactory.rollbackTransaction();
} catch (MobileDeviceManagementDAOException e1) {
log.warn("Error occurred while roll back the update device info transaction : '" +
device.toString() + "'", e1);
}
throw new DeviceManagementException(
"Error occurred while updating the Android device: '" +
device.getDeviceIdentifier() + "'", e);
}
return status;
}
@Override
public List<Device> getAllDevices() throws DeviceManagementException {
List<Device> devices = null;
try {
if (log.isDebugEnabled()) {
log.debug("Fetching the details of all Android devices");
}
List<MobileDevice> mobileDevices =
daoFactory.getMobileDeviceDAO().getAllMobileDevices();
if (mobileDevices != null) {
devices = new ArrayList<>(mobileDevices.size());
for (MobileDevice mobileDevice : mobileDevices) {
devices.add(MobileDeviceManagementUtil.convertToDevice(mobileDevice));
}
}
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while fetching all Android devices",
e);
}
return devices;
}
@Override
public void deleteDevices(List<String> deviceIdentifiers) throws DeviceManagementException {
//Does nothing since AndroidDeviceManager is not used instead DeviceTypeManager is used.
}
}

@ -1,580 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileFeatureDAO;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileFeature;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.MobileDeviceManagementUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class AndroidFeatureManager implements FeatureManager {
private MobileFeatureDAO featureDAO;
private static final Log log = LogFactory.getLog(AndroidFeatureManager.class);
public AndroidFeatureManager() {
MobileDeviceManagementDAOFactory daoFactory = new AndroidDAOFactory();
this.featureDAO = daoFactory.getMobileFeatureDAO();
}
@Override
public boolean addFeature(Feature feature) throws DeviceManagementException {
try {
AndroidDAOFactory.beginTransaction();
MobileFeature mobileFeature = MobileDeviceManagementUtil.convertToMobileFeature(feature);
featureDAO.addFeature(mobileFeature);
AndroidDAOFactory.commitTransaction();
return true;
} catch (MobileDeviceManagementDAOException e) {
try {
AndroidDAOFactory.rollbackTransaction();
} catch (MobileDeviceManagementDAOException e1) {
log.warn("Error occurred while roll-backing the transaction", e);
}
throw new DeviceManagementException("Error occurred while adding the feature", e);
}
}
@Override
public boolean addFeatures(List<Feature> features) throws DeviceManagementException {
List<MobileFeature> mobileFeatures = new ArrayList<MobileFeature>(features.size());
for (Feature feature : features) {
mobileFeatures.add(MobileDeviceManagementUtil.convertToMobileFeature(feature));
}
try {
AndroidDAOFactory.beginTransaction();
featureDAO.addFeatures(mobileFeatures);
AndroidDAOFactory.commitTransaction();
return true;
} catch (MobileDeviceManagementDAOException e) {
try {
AndroidDAOFactory.rollbackTransaction();
} catch (MobileDeviceManagementDAOException e1) {
log.warn("Error occurred while roll-backing the transaction", e);
}
throw new DeviceManagementException("Error occurred while adding the features", e);
}
}
@Override
public Feature getFeature(String name) throws DeviceManagementException {
try {
MobileFeature mobileFeature = featureDAO.getFeatureByCode(name);
Feature feature = MobileDeviceManagementUtil.convertToFeature(mobileFeature);
return feature;
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the feature", e);
}
}
@Override
public List<Feature> getFeatures() throws DeviceManagementException {
try {
List<MobileFeature> mobileFeatures = featureDAO.getAllFeatures();
return mobileFeatures.stream().map(MobileDeviceManagementUtil::convertToFeature).collect(
Collectors.toList());
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the list of features registered for " +
"Android platform", e);
}
}
@Override
public List<Feature> getFeatures(String featureType) throws DeviceManagementException {
if (StringUtils.isEmpty(featureType)) {
return this.getFeatures();
}
try {
List<MobileFeature> mobileFeatures = featureDAO.getFeaturesByFeatureType(featureType);
return mobileFeatures.stream().map(MobileDeviceManagementUtil::convertToFeature).collect(
Collectors.toList());
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the list of features registered for " +
"Android platform", e);
}
}
@Override
public List<Feature> getFeatures(String featureType, boolean isHidden) throws DeviceManagementException {
try {
List<MobileFeature> mobileFeatures;
if (StringUtils.isNotEmpty(featureType)) {
mobileFeatures = featureDAO.getFeaturesByFeatureType(featureType, isHidden);
} else {
mobileFeatures = featureDAO.getAllFeatures(isHidden);
}
return mobileFeatures.stream().map(MobileDeviceManagementUtil::convertToFeature).collect(
Collectors.toList());
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the list of features registered for " +
"Android platform", e);
}
}
@Override
public boolean removeFeature(String code) throws DeviceManagementException {
boolean status;
try {
AndroidDAOFactory.beginTransaction();
featureDAO.deleteFeatureByCode(code);
AndroidDAOFactory.commitTransaction();
status = true;
} catch (MobileDeviceManagementDAOException e) {
try {
AndroidDAOFactory.rollbackTransaction();
} catch (MobileDeviceManagementDAOException e1) {
log.warn("Error occurred while roll-backing the transaction", e);
}
throw new DeviceManagementException("Error occurred while removing the feature", e);
}
return status;
}
@Override
public boolean addSupportedFeaturesToDB() throws DeviceManagementException {
synchronized (this) {
List<Feature> supportedFeatures = getSupportedFeatures();
List<Feature> existingFeatures = this.getFeatures();
List<Feature> missingFeatures = MobileDeviceManagementUtil.
getMissingFeatures(supportedFeatures, existingFeatures);
if (missingFeatures.size() > 0) {
return this.addFeatures(missingFeatures);
}
return true;
}
}
//Get the supported feature list.
private static List<Feature> getSupportedFeatures() {
List<Feature> supportedFeatures = new ArrayList<Feature>();
Feature feature = new Feature();
feature.setCode("DEVICE_LOCK");
feature.setName("Device Lock");
feature.setDescription("Lock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DEVICE_LOCATION");
feature.setName("Location");
feature.setDescription("Request coordinates of device location");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("WIFI");
feature.setName("wifi");
feature.setDescription("Setting up wifi configuration");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("CAMERA");
feature.setName("camera");
feature.setDescription("Enable or disable camera");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("BACKUP_SERVICE");
feature.setName("Set Backup Service");
feature.setDescription("set backup service");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("EMAIL");
feature.setName("Email");
feature.setDescription("Configure email settings");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DEVICE_MUTE");
feature.setName("mute");
feature.setDescription("Enable mute in the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DEVICE_INFO");
feature.setName("Device info");
feature.setDescription("Request device information");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("ENTERPRISE_WIPE");
feature.setName("Enterprise Wipe");
feature.setDescription("Remove enterprise applications");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("CLEAR_PASSWORD");
feature.setName("Clear Password");
feature.setDescription("Clear current password");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("WIPE_DATA");
feature.setName("Wipe Data");
feature.setDescription("Factory reset the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("APPLICATION_LIST");
feature.setName("Application List");
feature.setDescription("Request list of current installed applications");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("CHANGE_LOCK_CODE");
feature.setName("Change Lock-code");
feature.setDescription("Change current lock code");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("INSTALL_APPLICATION");
feature.setName("Install App");
feature.setDescription("Install Enterprise or Market application");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("UNINSTALL_APPLICATION");
feature.setName("Uninstall App");
feature.setDescription("Uninstall application");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("BLACKLIST_APPLICATIONS");
feature.setName("Blacklist app");
feature.setDescription("Blacklist applications");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("ENCRYPT_STORAGE");
feature.setName("Encrypt storage");
feature.setDescription("Encrypt storage");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DEVICE_RING");
feature.setName("Ring");
feature.setDescription("Ring the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("PASSCODE_POLICY");
feature.setName("Password Policy");
feature.setDescription("Set passcode policy");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("NOTIFICATION");
feature.setName("Message");
feature.setDescription("Send message");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DEVICE_REBOOT");
feature.setName("Reboot");
feature.setDescription("Reboot the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("UPGRADE_FIRMWARE");
feature.setName("Upgrade Firmware");
feature.setDescription("Upgrade Firmware");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("VPN");
feature.setName("Configure VPN");
feature.setDescription("Configure VPN settings");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_ADJUST_VOLUME");
feature.setName("Adjust Volume");
feature.setDescription("allow or disallow user to change volume");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_BLUETOOTH");
feature.setName("Disallow bluetooth configuration");
feature.setDescription("allow or disallow user to change bluetooth configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_CELL_BROADCASTS");
feature.setName("Disallow cell broadcast configuration");
feature.setDescription("allow or disallow user to change cell broadcast configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_CREDENTIALS");
feature.setName("Disallow credential configuration");
feature.setDescription("allow or disallow user to change user credentials");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_MOBILE_NETWORKS");
feature.setName("Disallow mobile network configure");
feature.setDescription("allow or disallow user to change mobile networks configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_TETHERING");
feature.setName("Disallow tethering configuration");
feature.setDescription("allow or disallow user to change tethering configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_VPN");
feature.setName("Disallow VPN configuration");
feature.setDescription("allow or disallow user to change VPN configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CONFIG_WIFI");
feature.setName("Disallow WIFI configuration");
feature.setDescription("allow or disallow user to change WIFI configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_APPS_CONTROL");
feature.setName("Disallow APP control configuration");
feature.setDescription("allow or disallow user to change app control");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CREATE_WINDOWS");
feature.setName("Disallow window creation");
feature.setDescription("allow or disallow window creation");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_APPS_CONTROL");
feature.setName("Disallow APP control configuration");
feature.setDescription("allow or disallow user to change app control configurations");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_CROSS_PROFILE_COPY_PASTE");
feature.setName("Disallow cross profile copy paste");
feature.setDescription("allow or disallow cross profile copy paste");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_DEBUGGING_FEATURES");
feature.setName("Disallow debugging features");
feature.setDescription("allow or disallow debugging features");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_FACTORY_RESET");
feature.setName("Disallow factory reset");
feature.setDescription("allow or disallow factory reset");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_ADD_USER");
feature.setName("Disallow add user");
feature.setDescription("allow or disallow add user");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_INSTALL_APPS");
feature.setName("Disallow install apps");
feature.setDescription("allow or disallow install apps");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_INSTALL_UNKNOWN_SOURCES");
feature.setName("Disallow install unknown sources");
feature.setDescription("allow or disallow install unknown sources");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_MODIFY_ACCOUNTS");
feature.setName("Disallow modify account");
feature.setDescription("allow or disallow modify account");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_MOUNT_PHYSICAL_MEDIA");
feature.setName("Disallow mount physical media");
feature.setDescription("allow or disallow mount physical media.");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_NETWORK_RESET");
feature.setName("Disallow network reset");
feature.setDescription("allow or disallow network reset");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_OUTGOING_BEAM");
feature.setName("Disallow outgoing beam");
feature.setDescription("allow or disallow outgoing beam.");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_OUTGOING_CALLS");
feature.setName("Disallow outgoing calls");
feature.setDescription("allow or disallow outgoing calls");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_REMOVE_USER");
feature.setName("Disallow remove users");
feature.setDescription("allow or disallow remove users");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SAFE_BOOT");
feature.setName("Disallow safe boot");
feature.setDescription("allow or disallow safe boot");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SHARE_LOCATION");
feature.setName("Disallow share location");
feature.setDescription("allow or disallow share location.");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SMS");
feature.setName("Disallow sms");
feature.setDescription("allow or disallow sms");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_UNINSTALL_APPS");
feature.setName("Disallow uninstall app");
feature.setDescription("allow or disallow uninstall app");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_UNMUTE_MICROPHONE");
feature.setName("Disallow unmute mic");
feature.setDescription("allow or disallow unmute mic");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_USB_FILE_TRANSFER");
feature.setName("Disallow usb file transfer");
feature.setDescription("allow or disallow usb file transfer");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("ALLOW_PARENT_PROFILE_APP_LINKING");
feature.setName("Disallow parent profile app linking");
feature.setDescription("allow or disallow parent profile app linking");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("ENSURE_VERIFY_APPS");
feature.setName("Disallow ensure verify apps");
feature.setDescription("allow or disallow ensure verify apps");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("AUTO_TIME");
feature.setName("Allow auto timing");
feature.setDescription("allow or disallow auto timing");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("REMOVE_DEVICE_OWNER");
feature.setName("Remove device owner");
feature.setDescription("remove device owner");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("LOGCAT");
feature.setName("Fetch Logcat");
feature.setDescription("Fetch device logcat");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DEVICE_UNLOCK");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SET_WALLPAPER");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SET_USER_ICON");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_REMOVE_MANAGEMENT_PROFILE");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_AUTOFILL");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_BLUETOOTH");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_BLUETOOTH_SHARING");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_REMOVE_USER");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_DATA_ROAMING");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
return supportedFeatures;
}
}

@ -0,0 +1,218 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.mobile.android.AndroidPluginService;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.EnterpriseDAO;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.EnterpriseManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseManagedConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import java.util.List;
/**
* This represents the Android implementation of DeviceManagerService.
*/
public class AndroidPluginServiceImpl implements AndroidPluginService {
private static final Log log = LogFactory.getLog(AndroidPluginServiceImpl.class);
private EnterpriseDAO enterpriseDAO;
public AndroidPluginServiceImpl() {
enterpriseDAO = AndroidDAOFactory.getEnterpriseDAO();
}
@Override
public void addEnterpriseUser(AndroidEnterpriseUser androidEnterpriseUser) throws EnterpriseServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling add user service by device identifier: " + androidEnterpriseUser.getEmmDeviceId());
}
try {
AndroidDAOFactory.beginTransaction();
this.enterpriseDAO.addUser(androidEnterpriseUser);
AndroidDAOFactory.commitTransaction();
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while adding the user "
+ CarbonContext.getThreadLocalCarbonContext().getUsername();
log.error(msg, e);
AndroidDAOFactory.rollbackTransaction();
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<AndroidEnterpriseUser> getEnterpriseUser(String username) throws EnterpriseServiceException {
List<AndroidEnterpriseUser> androidEnterpriseUsers;
if (log.isDebugEnabled()) {
log.debug("Calling get user service by device identifier: " + CarbonContext
.getThreadLocalCarbonContext().getUsername());
}
try {
AndroidDAOFactory.openConnection();
androidEnterpriseUsers = this.enterpriseDAO.getUser(username, CarbonContext.getThreadLocalCarbonContext()
.getTenantId());
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while adding the user "
+ CarbonContext.getThreadLocalCarbonContext().getUsername();
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
return androidEnterpriseUsers;
}
@Override
public AndroidEnterpriseUser getEnterpriseUserByDevice(String deviceId) throws EnterpriseServiceException {
AndroidEnterpriseUser androidEnterpriseUsers;
if (log.isDebugEnabled()) {
log.debug("Calling get user service by device identifier: " + CarbonContext
.getThreadLocalCarbonContext().getUsername());
}
try {
AndroidDAOFactory.openConnection();
androidEnterpriseUsers = this.enterpriseDAO.getUserByDevice(deviceId, CarbonContext.getThreadLocalCarbonContext()
.getTenantId());
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while adding the user "
+ CarbonContext.getThreadLocalCarbonContext().getUsername();
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
return androidEnterpriseUsers;
}
@Override
public AndroidEnterpriseManagedConfig getConfigByPackageName(String packageName) throws EnterpriseServiceException {
AndroidEnterpriseManagedConfig enterpriseManagedConfig;
if (log.isDebugEnabled()) {
log.debug("Calling get user service by device identifier: " + CarbonContext
.getThreadLocalCarbonContext().getUsername());
}
try {
AndroidDAOFactory.openConnection();
enterpriseManagedConfig = this.enterpriseDAO.getConfigByPackageName(packageName, CarbonContext
.getThreadLocalCarbonContext().getTenantId());
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while getting configs for the package " + packageName;
log.error(msg, e);
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
return enterpriseManagedConfig;
}
@Override
public void addConfig(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseServiceException {
if (log.isDebugEnabled()) {
log.debug("Calling add managed config for package : " + managedConfig.getPackageName());
}
// Block from fetching other tenants data.
managedConfig.setTenantID(CarbonContext.getThreadLocalCarbonContext().getTenantId());
try {
AndroidDAOFactory.beginTransaction();
this.enterpriseDAO.addConfig(managedConfig);
AndroidDAOFactory.commitTransaction();
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while adding managed configs for package " + managedConfig.getPackageName();
log.error(msg, e);
AndroidDAOFactory.rollbackTransaction();
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
}
@Override
public boolean updateMobileDevice(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseServiceException {
boolean status;
if (log.isDebugEnabled()) {
log.debug("Calling update managed config for mcm id : " + managedConfig.getMcmId());
}
// Block from fetching other tenants data.
managedConfig.setTenantID(CarbonContext.getThreadLocalCarbonContext().getTenantId());
try {
AndroidDAOFactory.beginTransaction();
status = this.enterpriseDAO.updateConfig(managedConfig);
AndroidDAOFactory.commitTransaction();
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while updating managed configs for mcm id " + managedConfig.getMcmId();
log.error(msg, e);
AndroidDAOFactory.rollbackTransaction();
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
return status;
}
@Override
public boolean deleteMobileDevice(String id) throws EnterpriseServiceException {
boolean status;
if (log.isDebugEnabled()) {
log.debug("Calling update managed config for mcm id : " + id);
}
try {
AndroidDAOFactory.beginTransaction();
status = this.enterpriseDAO.deleteConfig(id,CarbonContext.getThreadLocalCarbonContext().getTenantId());
AndroidDAOFactory.commitTransaction();
} catch (EnterpriseManagementDAOException e) {
String msg = "Error occurred while updating managed configs for mcm id " + id;
log.error(msg, e);
AndroidDAOFactory.rollbackTransaction();
throw new EnterpriseServiceException(msg, e);
} finally {
AndroidDAOFactory.closeConnection();
}
return status;
}
}

@ -1,84 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl;
import com.google.gson.Gson;
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.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
import java.util.ArrayList;
import java.util.List;
public class AndroidPolicyMonitoringManager implements PolicyMonitoringManager {
private static Log log = LogFactory.getLog(AndroidPolicyMonitoringManager.class);
@Override
public NonComplianceData checkPolicyCompliance(DeviceIdentifier deviceIdentifier, Policy policy,
Object compliancePayload) throws PolicyComplianceException {
if (log.isDebugEnabled()) {
log.debug("Checking policy compliance status of device '" + deviceIdentifier.getId() + "'");
}
NonComplianceData complianceData = new NonComplianceData();
if (compliancePayload == null || policy == null) {
return complianceData;
}
String compliancePayloadString = new Gson().toJson(compliancePayload);
// Parsing json string to get compliance features.
JsonElement jsonElement;
if (compliancePayloadString instanceof String) {
jsonElement = new JsonParser().parse(compliancePayloadString);
} else {
throw new PolicyComplianceException("Invalid policy compliance payload");
}
JsonArray jsonArray = jsonElement.getAsJsonArray();
Gson gson = new Gson();
ComplianceFeature complianceFeature;
List<ComplianceFeature> complianceFeatures = new ArrayList<ComplianceFeature>(jsonArray.size());
List<ComplianceFeature> nonComplianceFeatures = new ArrayList<>();
for (JsonElement element : jsonArray) {
complianceFeature = gson.fromJson(element, ComplianceFeature.class);
complianceFeatures.add(complianceFeature);
}
for (ComplianceFeature cf : complianceFeatures) {
if (!cf.isCompliant()) {
complianceData.setStatus(false);
nonComplianceFeatures.add(cf);
break;
}
}
complianceData.setComplianceFeatures(nonComplianceFeatures);
return complianceData;
}
}

@ -0,0 +1,80 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl;
/**
* Custom exception class for enterprise specific data access related exceptions.
*/
public class EnterpriseServiceException extends Exception {
private String message;
private static final long serialVersionUID = 2021891706072918865L;
/**
* Constructs a new EnterpriseServiceException with the specified detail message and
* nested exception.
*
* @param message error message
* @param nestedException exception
*/
public EnterpriseServiceException(String message, Exception nestedException) {
super(message, nestedException);
setErrorMessage(message);
}
/**
* Constructs a new EnterpriseServiceException with the specified detail message
* and cause.
*
* @param message the detail message.
* @param cause the cause of this exception.
*/
public EnterpriseServiceException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
/**
* Constructs a new EnterpriseServiceException with the specified detail message.
*
* @param message the detail message.
*/
public EnterpriseServiceException(String message) {
super(message);
setErrorMessage(message);
}
/**
* Constructs a new EnterpriseServiceException with the specified and cause.
*
* @param cause the cause of this exception.
*/
public EnterpriseServiceException(Throwable cause) {
super(cause);
}
public String getMessage() {
return message;
}
public void setErrorMessage(String errorMessage) {
this.message = errorMessage;
}
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.config.datasource;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "iosDBConfigurations")
public class AndroidDataSourceConfigurations {
private MobileDataSourceConfig iosDataSourceConfiguration;
@XmlElement(name = "DataSourceConfiguration")
public MobileDataSourceConfig getIosDataSourceConfiguration() {
return iosDataSourceConfiguration;
}
public void setIosDataSourceConfiguration(MobileDataSourceConfig iosDataSourceConfiguration) {
this.iosDataSourceConfiguration = iosDataSourceConfiguration;
}
}

@ -34,7 +34,7 @@ import java.util.Map;
/**
* Factory class used to create MobileDeviceManagement related DAO objects.
*/
public abstract class AbstractMobileDeviceManagementDAOFactory implements MobileDeviceManagementDAOFactory {
public abstract class AbstractMobileDeviceManagementDAOFactory {
private static final Log log = LogFactory.getLog(AbstractMobileDeviceManagementDAOFactory.class);
private static Map<String, DataSource> dataSourceMap = new HashMap<>();

@ -21,8 +21,7 @@ package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl.AndroidDeviceDAOImpl;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl.AndroidFeatureDAOImpl;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl.EnterpriseDAOImpl;
import javax.sql.DataSource;
import java.sql.Connection;
@ -38,38 +37,52 @@ public class AndroidDAOFactory extends AbstractMobileDeviceManagementDAOFactory
this.dataSource = getDataSourceMap().get(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
}
@Override
public MobileDeviceDAO getMobileDeviceDAO() {
return new AndroidDeviceDAOImpl();
}
public static EnterpriseDAO getEnterpriseDAO() {
if (dataSource == null) {
dataSource = getDataSourceMap().get(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
}
public MobileFeatureDAO getMobileFeatureDAO() {
return new AndroidFeatureDAOImpl();
return new EnterpriseDAOImpl();
}
public static void beginTransaction() throws MobileDeviceManagementDAOException {
public static void beginTransaction() throws EnterpriseManagementDAOException {
try {
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false);
currentConnection.set(conn);
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while retrieving datasource connection", e);
throw new EnterpriseManagementDAOException("Error occurred while retrieving datasource connection", e);
}
}
public static void openConnection() throws EnterpriseManagementDAOException {
Connection conn = currentConnection.get();
if (conn != null) {
throw new EnterpriseManagementDAOException("A transaction is already active within the context of " +
"this particular thread. Therefore, calling 'beginTransaction/openConnection' while another " +
"transaction is already active is a sign of improper transaction handling");
}
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
throw new EnterpriseManagementDAOException("Error occurred while opening connection", e);
}
currentConnection.set(conn);
}
public static Connection getConnection() throws MobileDeviceManagementDAOException {
public static Connection getConnection() throws EnterpriseManagementDAOException {
if (currentConnection.get() == null) {
try {
currentConnection.set(dataSource.getConnection());
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while retrieving data source connection",
throw new EnterpriseManagementDAOException("Error occurred while retrieving data source connection",
e);
}
}
return currentConnection.get();
}
public static void commitTransaction() throws MobileDeviceManagementDAOException {
public static void commitTransaction() throws EnterpriseManagementDAOException {
try {
Connection conn = currentConnection.get();
if (conn != null) {
@ -81,11 +94,11 @@ public class AndroidDAOFactory extends AbstractMobileDeviceManagementDAOFactory
}
}
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while committing the transaction", e);
throw new EnterpriseManagementDAOException("Error occurred while committing the transaction", e);
}
}
public static void closeConnection() throws MobileDeviceManagementDAOException {
public static void closeConnection() {
Connection conn = currentConnection.get();
try {
if (conn != null) {
@ -97,7 +110,7 @@ public class AndroidDAOFactory extends AbstractMobileDeviceManagementDAOFactory
currentConnection.remove();
}
public static void rollbackTransaction() throws MobileDeviceManagementDAOException {
public static void rollbackTransaction() {
try {
Connection conn = currentConnection.get();
if (conn != null) {
@ -109,7 +122,7 @@ public class AndroidDAOFactory extends AbstractMobileDeviceManagementDAOFactory
}
}
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while rollback the transaction", e);
log.warn("Error occurred while roll-backing the transaction", e);
}
}

@ -1,77 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
public class AndroidFeatureManagementDAOException extends MobileDeviceManagementDAOException {
private String message;
private static final long serialVersionUID = 2021891706072918865L;
/**
* Constructs a new MobileDeviceManagementDAOException with the specified detail message and
* nested exception.
*
* @param message error message
* @param nestedException exception
*/
public AndroidFeatureManagementDAOException(String message, Exception nestedException) {
super(message, nestedException);
setErrorMessage(message);
}
/**
* Constructs a new MobileDeviceManagementDAOException with the specified detail message
* and cause.
*
* @param message the detail message.
* @param cause the cause of this exception.
*/
public AndroidFeatureManagementDAOException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
/**
* Constructs a new MobileDeviceManagementDAOException with the specified detail message.
*
* @param message the detail message.
*/
public AndroidFeatureManagementDAOException(String message) {
super(message);
setErrorMessage(message);
}
/**
* Constructs a new MobileDeviceManagementDAOException with the specified and cause.
*
* @param cause the cause of this exception.
*/
public AndroidFeatureManagementDAOException(Throwable cause) {
super(cause);
}
public String getMessage() {
return message;
}
public void setErrorMessage(String errorMessage) {
this.message = errorMessage;
}
}

@ -0,0 +1,52 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseManagedConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import java.util.List;
/**
* This class represents the key operations associated with working with Enterprise data
*/
public interface EnterpriseDAO {
/**
* Add a new user to Enterprise.
*
* @param androidEnterpriseUser Enterprise user and device details.
* @return User addition status.
* @throws EnterpriseManagementDAOException
*/
boolean addUser(AndroidEnterpriseUser androidEnterpriseUser) throws EnterpriseManagementDAOException;
List<AndroidEnterpriseUser> getUser(String username, int tenantId) throws EnterpriseManagementDAOException;
AndroidEnterpriseUser getUserByDevice(String deviceId, int tenantId) throws EnterpriseManagementDAOException;
AndroidEnterpriseManagedConfig getConfigByPackageName(String packageName, int tenantId)
throws EnterpriseManagementDAOException;
boolean addConfig(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseManagementDAOException;
boolean updateConfig(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseManagementDAOException;
boolean deleteConfig(String id, int tenantId) throws EnterpriseManagementDAOException;
}

@ -0,0 +1,97 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
/**
* Custom exception class for enterprise specific data access related exceptions.
*/
public class EnterpriseManagementDAOException extends Exception {
private String message;
private static final long serialVersionUID = 2021891702072938865L;
/**
* Constructs a new EnterpriseManagementDAOException with the specified detail message and
* nested exception.
*
* @param message error message
* @param nestedException exception
*/
public EnterpriseManagementDAOException(String message, Exception nestedException) {
super(message, nestedException);
setErrorMessage(message);
}
/**
* Constructs a new EnterpriseManagementDAOException with the specified detail message
* and cause.
*
* @param message the detail message.
* @param cause the cause of this exception.
*/
public EnterpriseManagementDAOException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
/**
* Constructs a new EnterpriseManagementDAOException with the specified detail message.
*
* @param message the detail message.
*/
public EnterpriseManagementDAOException(String message) {
super(message);
setErrorMessage(message);
}
/**
* Constructs a new EnterpriseManagementDAOException with the specified and cause.
*
* @param cause the cause of this exception.
*/
public EnterpriseManagementDAOException(Throwable cause) {
super(cause);
}
public String getMessage() {
return message;
}
public void setErrorMessage(String errorMessage) {
this.message = errorMessage;
}
}

@ -1,74 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileDevice;
import java.util.List;
/**
* This class represents the key operations associated with persisting mobile-device related
* information.
*/
public interface MobileDeviceDAO {
/**
* Fetches a MobileDevice from MDM database.
*
* @param mblDeviceId Id of the Mobile-Device.
* @return MobileDevice corresponding to given device-id.
* @throws MobileDeviceManagementDAOException
*/
MobileDevice getMobileDevice(String mblDeviceId) throws MobileDeviceManagementDAOException;
/**
* Adds a new MobileDevice to the MDM database.
*
* @param mobileDevice MobileDevice to be added.
* @return The status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean addMobileDevice(MobileDevice mobileDevice) throws MobileDeviceManagementDAOException;
/**
* Updates MobileDevice information in MDM database.
*
* @param mobileDevice MobileDevice to be updated.
* @return The status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean updateMobileDevice(MobileDevice mobileDevice) throws MobileDeviceManagementDAOException;
/**
* Deletes a given MobileDevice from MDM database.
*
* @param mblDeviceId Id of MobileDevice to be deleted.
* @return The status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean deleteMobileDevice(String mblDeviceId) throws MobileDeviceManagementDAOException;
/**
* Fetches all MobileDevices from MDM database.
*
* @return List of MobileDevices.
* @throws MobileDeviceManagementDAOException
*/
List<MobileDevice> getAllMobileDevices() throws MobileDeviceManagementDAOException;
}

@ -20,8 +20,5 @@ package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
public interface MobileDeviceManagementDAOFactory {
MobileDeviceDAO getMobileDeviceDAO();
MobileFeatureDAO getMobileFeatureDAO();
}

@ -1,156 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileFeature;
import java.util.List;
/**
* This class represents the key operations associated with persisting mobile feature related
* information.
*/
public interface MobileFeatureDAO {
/**
* Adds a new MobileFeature to Mobile-Feature table.
*
* @param mobileFeature MobileFeature object that holds data related to the feature to be inserted.
* @return boolean status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean addFeature(MobileFeature mobileFeature) throws MobileDeviceManagementDAOException;
/**
* Adda a list of MobileFeatures to Mobile-Feature table.
*
* @param mobileFeatures List of MobileFeature objects.
* @return boolean status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean addFeatures(List<MobileFeature> mobileFeatures) throws MobileDeviceManagementDAOException;
/**
* Updates a MobileFeature in Mobile-Feature table.
*
* @param mobileFeature MobileFeature object that holds data has to be updated.
* @return The status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean updateFeature(MobileFeature mobileFeature) throws MobileDeviceManagementDAOException;
/**
* Deletes a MobileFeature from Mobile-Feature table when the feature id is given.
*
* @param mblFeatureId MobileFeature id of the MobileFeature to be deleted.
* @return The status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean deleteFeatureById(int mblFeatureId) throws MobileDeviceManagementDAOException;
/**
* Deletes a MobileFeature from Mobile-Feature table when the feature code is given.
*
* @param mblFeatureCode MobileFeature code of the feature to be deleted.
* @return The status of the operation.
* @throws MobileDeviceManagementDAOException
*/
boolean deleteFeatureByCode(String mblFeatureCode) throws MobileDeviceManagementDAOException;
/**
* Retrieves a given MobileFeature from Mobile-Feature table when the feature id is given.
*
* @param mblFeatureId Feature id of the feature to be retrieved.
* @return MobileFeature object that holds data of the feature represented by featureId.
* @throws MobileDeviceManagementDAOException
*/
MobileFeature getFeatureById(int mblFeatureId) throws MobileDeviceManagementDAOException;
/**
* Retrieves a given MobileFeature from Mobile-Feature table when the feature code is given.
*
* @param mblFeatureCode Feature code of the feature to be retrieved.
* @return MobileFeature object that holds data of the feature represented by featureCode.
* @throws MobileDeviceManagementDAOException
*/
MobileFeature getFeatureByCode(String mblFeatureCode) throws MobileDeviceManagementDAOException;
/**
* Retrieves all MobileFeatures of a MobileDevice type from Mobile-Feature table.
*
* @param deviceType MobileDevice type of the MobileFeatures to be retrieved
* @return MobileFeature object list.
* @throws MobileDeviceManagementDAOException
*/
List<MobileFeature> getFeatureByDeviceType(String deviceType) throws MobileDeviceManagementDAOException;
/**
* Retrieve all the MobileFeatures from Mobile-Feature table.
*
* @return MobileFeature object list.
* @throws MobileDeviceManagementDAOException
*/
List<MobileFeature> getAllFeatures() throws MobileDeviceManagementDAOException;
/**
* Get all the MobileFeatures by a given ui visibility
*
* @param isHidden Whether the operation is hidden from UI or not.
* @return {@link MobileFeature} object list.
* @throws MobileDeviceManagementDAOException If an error occurred while retrieving the Feature list
*/
List<MobileFeature> getAllFeatures(boolean isHidden) throws MobileDeviceManagementDAOException;
/**
* Retrieve all MobileFeatures of a given feature type
*
* @param featureType Feature type.
* @return {@link MobileFeature} object list.
* @throws MobileDeviceManagementDAOException If an error occurred while retrieving the Feature list
*/
List<MobileFeature> getFeaturesByFeatureType(String featureType) throws MobileDeviceManagementDAOException;
/**
* Retrieve all MobileFeatures of a given feature type and ui visibility
*
* @param featureType Feature type.
* @param isHidden Whether the operation is hidden from UI or not.
* @return {@link MobileFeature} object list.
* @throws MobileDeviceManagementDAOException If an error occurred while retrieving the Feature list
*/
List<MobileFeature> getFeaturesByFeatureType(String featureType, boolean isHidden) throws MobileDeviceManagementDAOException;
}

@ -1,269 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceDAO;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.util.MobileDeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileDevice;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginConstants;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Implements MobileDeviceDAO for Android Devices.
*/
public class AndroidDeviceDAOImpl implements MobileDeviceDAO{
private static final Log log = LogFactory.getLog(AndroidDeviceDAOImpl.class);
@Override
public MobileDevice getMobileDevice(String mblDeviceId) throws MobileDeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
MobileDevice mobileDevice = null;
ResultSet rs = null;
try {
conn = AndroidDAOFactory.getConnection();
String selectDBQuery =
"SELECT DEVICE_ID, FCM_TOKEN, DEVICE_INFO, DEVICE_MODEL, SERIAL, " +
"VENDOR, MAC_ADDRESS, DEVICE_NAME, LATITUDE, LONGITUDE, IMEI, IMSI, OS_VERSION, OS_BUILD_DATE" +
" FROM AD_DEVICE WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setString(1, mblDeviceId);
rs = stmt.executeQuery();
if (rs.next()) {
mobileDevice = new MobileDevice();
mobileDevice.setMobileDeviceId(rs.getString(AndroidPluginConstants.DEVICE_ID));
mobileDevice.setModel(rs.getString(AndroidPluginConstants.DEVICE_MODEL));
mobileDevice.setSerial(rs.getString(AndroidPluginConstants.SERIAL));
mobileDevice.setVendor(rs.getString(AndroidPluginConstants.VENDOR));
mobileDevice.setLatitude(rs.getString(AndroidPluginConstants.LATITUDE));
mobileDevice.setLongitude(rs.getString(AndroidPluginConstants.LONGITUDE));
mobileDevice.setImei(rs.getString(AndroidPluginConstants.IMEI));
mobileDevice.setImsi(rs.getString(AndroidPluginConstants.IMSI));
mobileDevice.setOsVersion(rs.getString(AndroidPluginConstants.OS_VERSION));
mobileDevice.setOsBuildDate(rs.getString(AndroidPluginConstants.OS_BUILD_DATE));
Map<String, String> propertyMap = new HashMap<String, String>();
propertyMap.put(AndroidPluginConstants.FCM_TOKEN, rs.getString(AndroidPluginConstants.FCM_TOKEN));
propertyMap.put(AndroidPluginConstants.DEVICE_INFO, rs.getString(AndroidPluginConstants.DEVICE_INFO));
propertyMap.put(AndroidPluginConstants.DEVICE_NAME, rs.getString(AndroidPluginConstants.DEVICE_NAME));
mobileDevice.setDeviceProperties(propertyMap);
if (log.isDebugEnabled()) {
log.debug("Android device " + mblDeviceId + " data has been fetched from " +
"Android database.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while fetching Android device : '" + mblDeviceId + "'";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
return mobileDevice;
}
@Override
public boolean addMobileDevice(MobileDevice mobileDevice) throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String createDBQuery =
"INSERT INTO AD_DEVICE(DEVICE_ID, FCM_TOKEN, DEVICE_INFO, SERIAL, " +
"VENDOR, MAC_ADDRESS, DEVICE_NAME, LATITUDE, LONGITUDE, IMEI, IMSI, " +
"OS_VERSION, DEVICE_MODEL, OS_BUILD_DATE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(createDBQuery);
stmt.setString(1, mobileDevice.getMobileDeviceId());
Map<String, String> properties = mobileDevice.getDeviceProperties();
stmt.setString(2, properties.get(AndroidPluginConstants.FCM_TOKEN));
stmt.setString(3, properties.get(AndroidPluginConstants.DEVICE_INFO));
stmt.setString(4, mobileDevice.getSerial());
stmt.setString(5, mobileDevice.getVendor());
stmt.setString(6, mobileDevice.getMobileDeviceId());
stmt.setString(7, properties.get(AndroidPluginConstants.DEVICE_NAME));
stmt.setString(8, mobileDevice.getLatitude());
stmt.setString(9, mobileDevice.getLongitude());
stmt.setString(10, mobileDevice.getImei());
stmt.setString(11, mobileDevice.getImsi());
stmt.setString(12, mobileDevice.getOsVersion());
stmt.setString(13, mobileDevice.getModel());
stmt.setString(14, mobileDevice.getOsBuildDate());
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Android device " + mobileDevice.getMobileDeviceId() + " data has been" +
" added to the Android database.");
}
}
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while adding the Android device '" +
mobileDevice.getMobileDeviceId() + "' information to the Android plugin data store.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public boolean updateMobileDevice(MobileDevice mobileDevice) throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String updateDBQuery =
"UPDATE AD_DEVICE SET FCM_TOKEN = ?, DEVICE_INFO = ?, SERIAL = ?, VENDOR = ?, " +
"MAC_ADDRESS = ?, DEVICE_NAME = ?, LATITUDE = ?, LONGITUDE = ?, IMEI = ?, " +
"IMSI = ?, OS_VERSION = ?, DEVICE_MODEL = ?, OS_BUILD_DATE = ? WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(updateDBQuery);
Map<String, String> properties = mobileDevice.getDeviceProperties();
stmt.setString(1, properties.get(AndroidPluginConstants.FCM_TOKEN));
stmt.setString(2, properties.get(AndroidPluginConstants.DEVICE_INFO));
stmt.setString(3, mobileDevice.getSerial());
stmt.setString(4, mobileDevice.getVendor());
stmt.setString(5, properties.get(AndroidPluginConstants.MAC_ADDRESS));
stmt.setString(6, properties.get(AndroidPluginConstants.DEVICE_NAME));
stmt.setString(7, mobileDevice.getLatitude());
stmt.setString(8, mobileDevice.getLongitude());
stmt.setString(9, mobileDevice.getImei());
stmt.setString(10, mobileDevice.getImsi());
stmt.setString(11, mobileDevice.getOsVersion());
stmt.setString(12, mobileDevice.getModel());
stmt.setString(13, mobileDevice.getOsBuildDate());
stmt.setString(14, mobileDevice.getMobileDeviceId());
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Android device " + mobileDevice.getMobileDeviceId() + " data has been" +
" modified.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while modifying the Android device '" +
mobileDevice.getMobileDeviceId() + "' data.";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public boolean deleteMobileDevice(String mblDeviceId)
throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String deleteDBQuery =
"DELETE FROM AD_DEVICE WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(deleteDBQuery);
stmt.setString(1, mblDeviceId);
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Android device " + mblDeviceId + " data has deleted" +
" from the Android database.");
}
}
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while deleting android device '" +
mblDeviceId + "'", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public List<MobileDevice> getAllMobileDevices() throws MobileDeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
MobileDevice mobileDevice;
List<MobileDevice> mobileDevices = new ArrayList<MobileDevice>();
try {
conn = AndroidDAOFactory.getConnection();
String selectDBQuery =
"SELECT DEVICE_ID, FCM_TOKEN, DEVICE_INFO, DEVICE_MODEL, SERIAL, " +
"VENDOR, MAC_ADDRESS, DEVICE_NAME, LATITUDE, LONGITUDE, IMEI, IMSI, OS_VERSION, OS_BUILD_DATE " +
"FROM AD_DEVICE";
stmt = conn.prepareStatement(selectDBQuery);
rs = stmt.executeQuery();
while (rs.next()) {
mobileDevice = new MobileDevice();
mobileDevice.setMobileDeviceId(rs.getString(AndroidPluginConstants.DEVICE_ID));
mobileDevice.setModel(rs.getString(AndroidPluginConstants.DEVICE_MODEL));
mobileDevice.setSerial(rs.getString(AndroidPluginConstants.SERIAL));
mobileDevice.setVendor(rs.getString(AndroidPluginConstants.VENDOR));
mobileDevice.setLatitude(rs.getString(AndroidPluginConstants.LATITUDE));
mobileDevice.setLongitude(rs.getString(AndroidPluginConstants.LONGITUDE));
mobileDevice.setImei(rs.getString(AndroidPluginConstants.IMEI));
mobileDevice.setImsi(rs.getString(AndroidPluginConstants.IMSI));
mobileDevice.setOsVersion(rs.getString(AndroidPluginConstants.OS_VERSION));
mobileDevice.setOsBuildDate(rs.getString(AndroidPluginConstants.OS_BUILD_DATE));
Map<String, String> propertyMap = new HashMap<>();
propertyMap.put(AndroidPluginConstants.FCM_TOKEN, rs.getString(AndroidPluginConstants.FCM_TOKEN));
propertyMap.put(AndroidPluginConstants.DEVICE_INFO, rs.getString(AndroidPluginConstants.DEVICE_INFO));
propertyMap.put(AndroidPluginConstants.DEVICE_NAME, rs.getString(AndroidPluginConstants.DEVICE_NAME));
mobileDevice.setDeviceProperties(propertyMap);
mobileDevices.add(mobileDevice);
}
if (log.isDebugEnabled()) {
log.debug("All Android device details have fetched from Android database.");
}
return mobileDevices;
} catch (SQLException e) {
throw new MobileDeviceManagementDAOException("Error occurred while fetching all Android device data", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
}

@ -1,397 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidFeatureManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileFeatureDAO;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.util.MobileDeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileFeature;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginConstants;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
private static final Log log = LogFactory.getLog(AndroidFeatureDAOImpl.class);
public AndroidFeatureDAOImpl() {
}
@Override
public boolean addFeature(MobileFeature mobileFeature) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
boolean status = false;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "INSERT INTO AD_FEATURE(CODE, NAME, TYPE, HIDDEN, DESCRIPTION) VALUES (?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
stmt.setString(1, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getName());
stmt.setString(3, mobileFeature.getType());
stmt.setBoolean(4, mobileFeature.isHidden());
stmt.setString(5, mobileFeature.getDescription());
stmt.executeUpdate();
status = true;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while adding android feature '" +
mobileFeature.getName() + "' into the metadata repository", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public boolean addFeatures(List<MobileFeature> mobileFeatures) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
stmt = conn.prepareStatement("INSERT INTO AD_FEATURE(CODE, NAME, TYPE, HIDDEN, DESCRIPTION) " +
"VALUES (?, ?, ?, ?, ?)");
for (MobileFeature mobileFeature : mobileFeatures) {
stmt.setString(1, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getName());
stmt.setString(3, mobileFeature.getType());
stmt.setBoolean(4, mobileFeature.isHidden());
stmt.setString(5, mobileFeature.getDescription());
stmt.addBatch();
}
stmt.executeBatch();
return true;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while adding android features into the metadata repository", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
}
@Override
public boolean updateFeature(MobileFeature mobileFeature) throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String updateDBQuery =
"UPDATE AD_FEATURE SET NAME = ?, TYPE = ?, HIDDEN = ? ,DESCRIPTION = ?" +
"WHERE CODE = ?";
stmt = conn.prepareStatement(updateDBQuery);
stmt.setString(1, mobileFeature.getName());
stmt.setString(2, mobileFeature.getType());
stmt.setBoolean(3, mobileFeature.isHidden());
stmt.setString(4, mobileFeature.getDescription());
stmt.setString(5, mobileFeature.getCode());
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Android Feature " + mobileFeature.getCode() + " data has been " +
"modified.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while updating the Android Feature '" +
mobileFeature.getCode() + "' to the Android db.";
log.error(msg, e);
throw new AndroidFeatureManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public boolean deleteFeatureById(int mblFeatureId) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
boolean status = false;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "DELETE FROM AD_FEATURE WHERE ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, mblFeatureId);
stmt.execute();
status = true;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while deleting android feature '" +
mblFeatureId + "' from Android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public boolean deleteFeatureByCode(String mblFeatureCode) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
boolean status;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "DELETE FROM AD_FEATURE WHERE CODE = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, mblFeatureCode);
stmt.execute();
status = true;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while deleting android feature '" +
mblFeatureCode + "' from Android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
public MobileFeature getFeatureById(int mblFeatureId) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, mblFeatureId);
rs = stmt.executeQuery();
MobileFeature mobileFeature = null;
if (rs.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(rs.getInt(AndroidPluginConstants.ANDROID_FEATURE_ID));
mobileFeature.setCode(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_CODE));
mobileFeature.setName(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_NAME));
mobileFeature.setType(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_TYPE));
mobileFeature.setHidden(rs.getBoolean(AndroidPluginConstants.ANDROID_FEATURE_HIDDEN));
mobileFeature.setDescription(rs.getString(AndroidPluginConstants.
ANDROID_FEATURE_DESCRIPTION));
mobileFeature.setDeviceType(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
}
return mobileFeature;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while retrieving android feature '" +
mblFeatureId + "' from the Android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public MobileFeature getFeatureByCode(String mblFeatureCode) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE CODE = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, mblFeatureCode);
rs = stmt.executeQuery();
MobileFeature mobileFeature = null;
if (rs.next()) {
mobileFeature = populateMobileFeature(rs);
}
return mobileFeature;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while retrieving android feature '" +
mblFeatureCode + "' from the Android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getFeatureByDeviceType(String deviceType)
throws MobileDeviceManagementDAOException {
return this.getAllFeatures();
}
@Override
public List<MobileFeature> getAllFeatures() throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn = null;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features " +
"from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getAllFeatures(boolean isHidden) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn = null;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE HIDDEN = ?";
stmt = conn.prepareStatement(sql);
stmt.setBoolean(1, isHidden);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features " +
"from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getFeaturesByFeatureType(String featureType) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE TYPE = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, featureType);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features of " +
"type " + featureType + " from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getFeaturesByFeatureType(String featureType, boolean isHidden) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION " +
"FROM AD_FEATURE " +
"WHERE TYPE = ? AND HIDDEN = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, featureType);
stmt.setBoolean(2, isHidden);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features of " +
"[type: " + featureType + " & hidden: " + isHidden + "] from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
/**
* Generate {@link MobileFeature} from the SQL {@link ResultSet}
*
* @param rs Result set
* @return populated {@link MobileFeature}
* @throws SQLException if unable to extract data from {@link ResultSet}
*/
private MobileFeature populateMobileFeature(ResultSet rs) throws SQLException {
MobileFeature mobileFeature = new MobileFeature();
mobileFeature.setId(rs.getInt(AndroidPluginConstants.ANDROID_FEATURE_ID));
mobileFeature.setCode(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_CODE));
mobileFeature.setName(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_NAME));
mobileFeature.setDescription(rs.getString(AndroidPluginConstants.
ANDROID_FEATURE_DESCRIPTION));
mobileFeature.setType(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_TYPE));
mobileFeature.setHidden(rs.getBoolean(AndroidPluginConstants.ANDROID_FEATURE_HIDDEN));
mobileFeature.setDeviceType(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
return mobileFeature;
}
}

@ -0,0 +1,294 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AndroidDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.EnterpriseDAO;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.EnterpriseManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.util.MobileDeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseManagedConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.AndroidEnterpriseUser;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileDevice;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginConstants;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Implements EnterpriseDAO for Android Devices.
*/
public class EnterpriseDAOImpl implements EnterpriseDAO {
private static final Log log = LogFactory.getLog(EnterpriseDAOImpl.class);
public List<AndroidEnterpriseUser> getUser(String username, int tenantId) throws EnterpriseManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
List<AndroidEnterpriseUser> enterpriseUsers = new ArrayList<>();
ResultSet rs = null;
try {
conn = AndroidDAOFactory.getConnection();
String selectDBQuery =
"SELECT * FROM AD_ENTERPRISE_USER_DEVICE WHERE EMM_USERNAME = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setString(1, username);
stmt.setInt(2, tenantId);
rs = stmt.executeQuery();
while (rs.next()) {
AndroidEnterpriseUser enterpriseUser = new AndroidEnterpriseUser();
enterpriseUser.setEmmUsername(rs.getString("EMM_USERNAME"));
enterpriseUser.setTenantId(rs.getInt("TENANT_ID"));
enterpriseUser.setLastUpdatedTime(rs.getString("LAST_UPDATED_TIMESTAMP"));
enterpriseUser.setAndroidPlayDeviceId(rs.getString("ANDROID_PLAY_DEVICE_ID"));
enterpriseUser.setEnterpriseId(rs.getString("ENTERPRISE_ID"));
enterpriseUser.setGoogleUserId(rs.getString("GOOGLE_USER_ID"));
enterpriseUser.setEmmDeviceId(rs.getString("EMM_DEVICE_ID"));
enterpriseUsers.add(enterpriseUser);
}
} catch (SQLException e) {
String msg = "Error occurred while fetching user : '" + username + "'";
log.error(msg, e);
throw new EnterpriseManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
return enterpriseUsers;
}
public AndroidEnterpriseUser getUserByDevice(String deviceId, int tenantId) throws
EnterpriseManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
AndroidEnterpriseUser enterpriseUser = null;
ResultSet rs = null;
try {
conn = AndroidDAOFactory.getConnection();
String selectDBQuery =
"SELECT * FROM AD_ENTERPRISE_USER_DEVICE WHERE EMM_DEVICE_ID = ? AND TENANT_ID = ? " +
"ORDER BY LAST_UPDATED_TIMESTAMP DESC";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setString(1, deviceId);
stmt.setInt(2, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
enterpriseUser = new AndroidEnterpriseUser();
enterpriseUser.setEmmUsername(rs.getString("EMM_USERNAME"));
enterpriseUser.setTenantId(rs.getInt("TENANT_ID"));
enterpriseUser.setLastUpdatedTime(rs.getString("LAST_UPDATED_TIMESTAMP"));
enterpriseUser.setAndroidPlayDeviceId(rs.getString("ANDROID_PLAY_DEVICE_ID"));
enterpriseUser.setEnterpriseId(rs.getString("ENTERPRISE_ID"));
enterpriseUser.setGoogleUserId(rs.getString("GOOGLE_USER_ID"));
enterpriseUser.setEmmDeviceId(rs.getString("EMM_DEVICE_ID"));
}
} catch (SQLException e) {
String msg = "Error occurred while fetching user for device : '" + deviceId + "'";
log.error(msg, e);
throw new EnterpriseManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
return enterpriseUser;
}
public boolean addUser(AndroidEnterpriseUser androidEnterpriseUser) throws EnterpriseManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String createDBQuery =
"INSERT INTO AD_ENTERPRISE_USER_DEVICE(EMM_USERNAME, TENANT_ID, LAST_UPDATED_TIMESTAMP" +
", ANDROID_PLAY_DEVICE_ID, ENTERPRISE_ID, GOOGLE_USER_ID, EMM_DEVICE_ID)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(createDBQuery);
stmt.setString(1, androidEnterpriseUser.getEmmUsername());
stmt.setInt(2, androidEnterpriseUser.getTenantId());
stmt.setTimestamp(3, new Timestamp(new Date().getTime()));
stmt.setString(4, androidEnterpriseUser.getAndroidPlayDeviceId());
stmt.setString(5, androidEnterpriseUser.getEnterpriseId());
stmt.setString(6, androidEnterpriseUser.getGoogleUserId());
stmt.setString(7, androidEnterpriseUser.getEmmDeviceId());
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Added user " + androidEnterpriseUser.getEmmUsername());
}
}
} catch (SQLException e) {
throw new EnterpriseManagementDAOException("Error occurred while adding the user "
+ androidEnterpriseUser.getEmmUsername(), e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
public AndroidEnterpriseManagedConfig getConfigByPackageName(String packageName, int tenantId)
throws EnterpriseManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
AndroidEnterpriseManagedConfig managedConfig = null;
try {
conn = AndroidDAOFactory.getConnection();
String selectDBQuery =
"SELECT * FROM AD_ENTERPRISE_MANAGED_CONFIGS WHERE PACKAGE_NAME = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setString(1, packageName);
stmt.setInt(2, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
managedConfig = new AndroidEnterpriseManagedConfig();
managedConfig.setId(rs.getInt("ID"));
managedConfig.setMcmId(rs.getString("MCM_ID"));
managedConfig.setProfileName(rs.getString("PROFILE_NAME"));
managedConfig.setPackageName(rs.getString("PACKAGE_NAME"));
managedConfig.setTenantID(rs.getInt("TENANT_ID"));
managedConfig.setLastUpdatedTime(rs.getString("LAST_UPDATED_TIMESTAMP"));
}
} catch (SQLException e) {
String msg = "Error occurred while fetching config for package name : '" + packageName + "'";
log.error(msg, e);
throw new EnterpriseManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
return managedConfig;
}
public boolean addConfig(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String createDBQuery =
"INSERT INTO AD_ENTERPRISE_MANAGED_CONFIGS(MCM_ID, PROFILE_NAME, PACKAGE_NAME" +
", TENANT_ID, LAST_UPDATED_TIMESTAMP) VALUES (?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(createDBQuery);
stmt.setString(1, managedConfig.getMcmId());
stmt.setString(2, managedConfig.getProfileName());
stmt.setString(3, managedConfig.getPackageName());
stmt.setInt(4, managedConfig.getTenantID());
stmt.setTimestamp(5, new Timestamp(new Date().getTime()));
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Added config for package " + managedConfig.getPackageName());
}
}
} catch (SQLException e) {
throw new EnterpriseManagementDAOException("Error occurred while adding the config for package "
+ managedConfig.getPackageName(), e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
public boolean updateConfig(AndroidEnterpriseManagedConfig managedConfig) throws EnterpriseManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String updateDBQuery =
"UPDATE AD_ENTERPRISE_MANAGED_CONFIGS SET PROFILE_NAME = ?, LAST_UPDATED_TIMESTAMP = ?" +
" WHERE MCM_ID = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(updateDBQuery);
stmt.setString(1, managedConfig.getProfileName());
stmt.setString(2, managedConfig.getLastUpdatedTime());
stmt.setString(3, managedConfig.getMcmId());
stmt.setInt(4, managedConfig.getTenantID());
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Managed config for mcm id " + managedConfig.getMcmId() + " data has been" +
" modified.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while modifying the details for mcm id '" +
managedConfig.getMcmId() + "' data.";
log.error(msg, e);
throw new EnterpriseManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
public boolean deleteConfig(String id, int tenantId)
throws EnterpriseManagementDAOException {
boolean status = false;
Connection conn;
PreparedStatement stmt = null;
try {
conn = AndroidDAOFactory.getConnection();
String deleteDBQuery =
"DELETE FROM AD_ENTERPRISE_MANAGED_CONFIGS WHERE MCM_ID = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(deleteDBQuery);
stmt.setString(1, id);
stmt.setInt(2, tenantId);
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Error when deleting MCM ID " + id);
}
}
} catch (SQLException e) {
throw new EnterpriseManagementDAOException("Error occurred while deleting MCM ID '" + id + "'", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
}

@ -0,0 +1,78 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dto;
public class AndroidEnterpriseManagedConfig {
String mcmId;
String profileName;
String packageName;
int tenantID;
String lastUpdatedTime;
int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMcmId() {
return mcmId;
}
public void setMcmId(String mcmId) {
this.mcmId = mcmId;
}
public String getProfileName() {
return profileName;
}
public void setProfileName(String profileName) {
this.profileName = profileName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public int getTenantID() {
return tenantID;
}
public void setTenantID(int tenantID) {
this.tenantID = tenantID;
}
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(String lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
}

@ -0,0 +1,85 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dto;
public class AndroidEnterpriseUser {
String emmUsername;
int tenantId;
String enterpriseId;//from configs
String googleUserId;// generated internally
String androidPlayDeviceId; //sent by device
String emmDeviceId; //set internally
String lastUpdatedTime; //set internally
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(String lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
public String getEmmUsername() {
return emmUsername;
}
public void setEmmUsername(String emmUsername) {
this.emmUsername = emmUsername;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public String getEnterpriseId() {
return enterpriseId;
}
public void setEnterpriseId(String enterpriseId) {
this.enterpriseId = enterpriseId;
}
public String getGoogleUserId() {
return googleUserId;
}
public void setGoogleUserId(String googleUserId) {
this.googleUserId = googleUserId;
}
public String getAndroidPlayDeviceId() {
return androidPlayDeviceId;
}
public void setAndroidPlayDeviceId(String androidPlayDeviceId) {
this.androidPlayDeviceId = androidPlayDeviceId;
}
public String getEmmDeviceId() {
return emmDeviceId;
}
public void setEmmDeviceId(String emmDeviceId) {
this.emmDeviceId = emmDeviceId;
}
}

@ -1,45 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.dto;
/**
* DTO of Mobile feature property. Represents a property of a mobile feature.
*/
public class MobileFeatureProperty {
private String property;
private Integer featureID;
public Integer getFeatureID() {
return featureID;
}
public void setFeatureID(Integer featureID) {
this.featureID = featureID;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
}

@ -1,58 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.util;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
import org.wso2.carbon.device.mgt.mobile.android.impl.AndroidDeviceManagementService;
/**
* Contains utility methods used by Android plugin.
*/
public class AndroidPluginUtils {
public static License getDefaultLicense() {
License license = new License();
license.setName(AndroidDeviceManagementService.DEVICE_TYPE_ANDROID);
license.setLanguage("en_US");
license.setVersion("1.0.0");
license.setText("This End User License Agreement (\"Agreement\") is a legal agreement between you (\"You\") " +
"and WSO2, Inc., regarding the enrollment of Your personal mobile device (\"Device\") in SoR's " +
"mobile device management program, and the loading to and removal from Your Device and Your use " +
"of certain applications and any associated software and user documentation, whether provided in " +
"\"online\" or electronic format, used in connection with the operation of or provision of services " +
"to WSO2, Inc., BY SELECTING \"I ACCEPT\" DURING INSTALLATION, YOU ARE ENROLLING YOUR DEVICE, AND " +
"THEREBY AUTHORIZING SOR OR ITS AGENTS TO INSTALL, UPDATE AND REMOVE THE APPS FROM YOUR DEVICE AS " +
"DESCRIBED IN THIS AGREEMENT. YOU ARE ALSO EXPLICITLY ACKNOWLEDGING AND AGREEING THAT (1) THIS IS " +
"A BINDING CONTRACT AND (2) YOU HAVE READ AND AGREE TO THE TERMS OF THIS AGREEMENT.\n" +
"\n" +
"IF YOU DO NOT ACCEPT THESE TERMS, DO NOT ENROLL YOUR DEVICE AND DO NOT PROCEED ANY FURTHER.\n" +
"\n" +
"You agree that: (1) You understand and agree to be bound by the terms and conditions contained " +
"in this Agreement, and (2) You are at least 21 years old and have the legal capacity to enter " +
"into this Agreement as defined by the laws of Your jurisdiction. SoR shall have the right, " +
"without prior notice, to terminate or suspend (i) this Agreement, (ii) the enrollment of Your " +
"Device, or (iii) the functioning of the Apps in the event of a violation of this Agreement or " +
"the cessation of Your relationship with SoR (including termination of Your employment if You are " +
"an employee or expiration or termination of Your applicable franchise or supply agreement if You " +
"are a franchisee of or supplier to the WSO2 WSO2, Inc., system). SoR expressly reserves all " +
"rights not expressly granted herein.");
return license;
}
}

@ -1,31 +0,0 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.android.impl.util;
import java.util.Map;
/**
* Contains utility methods used by Android plugin.
*/
public class AndroidUtils {
public static String getDeviceProperty(Map<String, String> deviceProperties, String property) {
return deviceProperties.get(property);
}
}

@ -45,6 +45,9 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.mobile.android.impl.config.datasource.AndroidDataSourceConfigurations;
import org.wso2.carbon.device.mgt.mobile.android.impl.config.datasource.MobileDataSourceConfig;
import org.wso2.carbon.device.mgt.mobile.android.impl.config.datasource.MobileDataSourceConfigurations;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.impl.AndroidDeviceMgtPluginException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileDevice;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileDeviceOperationMapping;
@ -55,8 +58,11 @@ import org.wso2.carbon.device.mgt.mobile.android.internal.AndroidDeviceManagemen
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.utils.CarbonUtils;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
@ -373,4 +379,37 @@ public class MobileDeviceManagementUtil {
}
return missingFeatures;
}
public static final String IOS_DB_CONFIG_PATH = CarbonUtils.getCarbonConfigDirPath() + File.separator +
"/android-dbconfig.xml";
public static AndroidDataSourceConfigurations iosDataSourceConfigurations;
public static AndroidDataSourceConfigurations getIosDataSourceConfigurations() {
return iosDataSourceConfigurations;
}
public static synchronized void initConfig() throws DeviceManagementException {
try {
File mobileDeviceMgtConfig = new File(IOS_DB_CONFIG_PATH);
Document doc = convertToDocuments(mobileDeviceMgtConfig);
JAXBContext iosDeviceMgtContext = JAXBContext.newInstance(AndroidDataSourceConfigurations.class);
Unmarshaller unmarshaller = iosDeviceMgtContext.createUnmarshaller();
iosDataSourceConfigurations = (AndroidDataSourceConfigurations) unmarshaller.unmarshal(doc);
} catch (Exception e) {
throw new DeviceManagementException(
"Error occurred while initializing Mobile Device Management config", e);
}
}
public static Document convertToDocuments(File file) throws DeviceManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
DocumentBuilder docBuilder = factory.newDocumentBuilder();
return docBuilder.parse(file);
} catch (Exception e) {
throw new DeviceManagementException("Error occurred while parsing file, while converting " +
"to a org.w3c.dom.Document : " + e.getMessage(), e);
}
}
}

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.mobile.android.internal;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.mobile.android.AndroidPluginService;
import org.wso2.carbon.registry.core.service.RegistryService;
/**
@ -27,7 +28,7 @@ import org.wso2.carbon.registry.core.service.RegistryService;
public class AndroidDeviceManagementDataHolder {
private RegistryService registryService;
private DeviceManagementService androidDeviceManagementService;
private AndroidPluginService androidDeviceManagementService;
private static AndroidDeviceManagementDataHolder thisInstance = new AndroidDeviceManagementDataHolder();
@ -46,12 +47,12 @@ public class AndroidDeviceManagementDataHolder {
this.registryService = registryService;
}
public DeviceManagementService getAndroidDeviceManagementService() {
public AndroidPluginService getAndroidDeviceManagementService() {
return androidDeviceManagementService;
}
public void setAndroidDeviceManagementService(
DeviceManagementService androidDeviceManagementService) {
AndroidPluginService androidDeviceManagementService) {
this.androidDeviceManagementService = androidDeviceManagementService;
}

@ -20,14 +20,17 @@ package org.wso2.carbon.device.mgt.mobile.android.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.mobile.android.impl.AndroidDeviceManagementService;
import org.wso2.carbon.device.mgt.mobile.android.AndroidPluginService;
import org.wso2.carbon.device.mgt.mobile.android.impl.AndroidPluginServiceImpl;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.AbstractMobileDeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.MobileDeviceManagementUtil;
import org.wso2.carbon.ndatasource.core.DataSourceService;
import org.wso2.carbon.registry.core.service.RegistryService;
/**
* @scr.component name="org.wso2.carbon.device.mgt.mobile.android.impl.internal.AndroidDeviceManagementServiceComponent"
* @scr.component name="org.wso2.carbon.device.mgt.mobile.android.impl.internal.AndroidPluginServiceComponent"
* immediate="true"
* @scr.reference name="org.wso2.carbon.ndatasource"
* interface="org.wso2.carbon.ndatasource.core.DataSourceService"
@ -43,9 +46,9 @@ import org.wso2.carbon.registry.core.service.RegistryService;
* initializing APIMgtDAOs attempting to register APIs programmatically. APIMgtDAO needs to be proper cleaned up
* to avoid as an ideal fix
*/
public class AndroidDeviceManagementServiceComponent {
public class AndroidPluginServiceComponent {
private static final Log log = LogFactory.getLog(AndroidDeviceManagementServiceComponent.class);
private static final Log log = LogFactory.getLog(AndroidPluginServiceComponent.class);
protected void activate(ComponentContext ctx) {
@ -53,9 +56,17 @@ public class AndroidDeviceManagementServiceComponent {
log.debug("Activating Android Mobile Device Management Service Component");
}
try {
DeviceManagementService androidDeviceManagementService = new AndroidDeviceManagementService();
BundleContext bundleContext = ctx.getBundleContext();
MobileDeviceManagementUtil.initConfig();
AbstractMobileDeviceManagementDAOFactory.init("android", MobileDeviceManagementUtil
.getIosDataSourceConfigurations().getIosDataSourceConfiguration());
AndroidPluginService androidPluginService = new AndroidPluginServiceImpl();
AndroidDeviceManagementDataHolder.getInstance().setAndroidDeviceManagementService(
androidDeviceManagementService);
androidPluginService);
bundleContext.registerService(AndroidPluginService.class.getName(), androidPluginService, null);
if (log.isDebugEnabled()) {
log.debug("Android Mobile Device Management Service Component has been successfully activated");
}

@ -0,0 +1,25 @@
<!--
~ /*
~ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~ *
~ * WSO2 Inc. licenses this file to you under the Apache License,
~ * Version 2.0 (the "License"); you may not use this file except
~ * in compliance with the License.
~ * You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing,
~ * software distributed under the License is distributed on an
~ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ * KIND, either express or implied. See the License for the
~ * specific language governing permissions and limitations
~ * under the License.
-->
<iosDBConfigurations>
<DataSourceConfiguration>
<JndiLookupDefinition>
<Name>jdbc/MobileAndroidDM_DS</Name>
</JndiLookupDefinition>
</DataSourceConfiguration>
</iosDBConfigurations>

@ -31,3 +31,31 @@ CREATE TABLE IF NOT EXISTS `AD_FEATURE` (
`DESCRIPTION` VARCHAR(200) NULL,
PRIMARY KEY (`ID`));
-- -----------------------------------------------------
-- Table `AD_ENTERPRISE_USER_DEVICE`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `AD_ENTERPRISE_USER_DEVICE` (
`ID` INT NOT NULL AUTO_INCREMENT,
`ENTERPRISE_ID` VARCHAR(50) NULL,
`EMM_USERNAME` VARCHAR(100) NOT NULL,
`GOOGLE_USER_ID` VARCHAR(50) NULL,
`ANDROID_PLAY_DEVICE_ID` VARCHAR(50) NULL,
`EMM_DEVICE_ID` VARCHAR(50) NULL,
`TENANT_ID` INT(11) NULL DEFAULT '0',
`LAST_UPDATED_TIMESTAMP` TIMESTAMP NOT NULL,
PRIMARY KEY (`ID`));
-- -----------------------------------------------------
-- Table `AD_ENTERPRISE_MANAGED_CONFIGS`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `AD_ENTERPRISE_MANAGED_CONFIGS` (
`ID` INT NOT NULL AUTO_INCREMENT,
`MCM_ID` VARCHAR(50) NULL,
`PROFILE_NAME` VARCHAR(100) NULL,
`PACKAGE_NAME` VARCHAR(100) NOT NULL,
`TENANT_ID` INT(11) NULL DEFAULT '0',
`LAST_UPDATED_TIMESTAMP` TIMESTAMP NOT NULL,
PRIMARY KEY (`ID`));

@ -32,3 +32,25 @@ CREATE TABLE AD_FEATURE (
DESCRIPTION VARCHAR(200) NULL,
PRIMARY KEY (ID)
);
CREATE TABLE AD_ENTERPRISE_USER_DEVICE (
[ID] INT NOT NULL IDENTITY,
[ENTERPRISE_ID] VARCHAR(50) NULL,
[EMM_USERNAME] VARCHAR(100) NOT NULL,
[GOOGLE_USER_ID] VARCHAR(50) NULL,
[ANDROID_PLAY_DEVICE_ID] VARCHAR(50) NULL,
[EMM_DEVICE_ID] VARCHAR(50) NULL,
[TENANT_ID] INT NULL DEFAULT '0',
[LAST_UPDATED_TIMESTAMP] DATETIME2(0) NOT NULL,
PRIMARY KEY ([ID])
);
CREATE TABLE AD_ENTERPRISE_MANAGED_CONFIGS (
[ID] INT NOT NULL IDENTITY,
[MCM_ID] VARCHAR(50) NULL,
[PROFILE_NAME] VARCHAR(100) NULL,
[PACKAGE_NAME] VARCHAR(100) NOT NULL,
[TENANT_ID] INT NULL DEFAULT '0',
[LAST_UPDATED_TIMESTAMP] DATETIME2(0) NOT NULL,
PRIMARY KEY ([ID])
) ;

@ -31,3 +31,26 @@ CREATE TABLE IF NOT EXISTS `AD_FEATURE` (
`DESCRIPTION` VARCHAR(200) NULL,
PRIMARY KEY (`ID`)
) ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `AD_ENTERPRISE_USER_DEVICE` (
`ID` INT NOT NULL AUTO_INCREMENT,
`ENTERPRISE_ID` VARCHAR(50) NULL,
`EMM_USERNAME` VARCHAR(100) NOT NULL,
`GOOGLE_USER_ID` VARCHAR(50) NULL,
`ANDROID_PLAY_DEVICE_ID` VARCHAR(50) NULL,
`EMM_DEVICE_ID` VARCHAR(50) NULL,
`TENANT_ID` INT(11) NULL DEFAULT '0',
`LAST_UPDATED_TIMESTAMP` TIMESTAMP NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `AD_ENTERPRISE_MANAGED_CONFIGS` (
`ID` INT NOT NULL AUTO_INCREMENT,
`MCM_ID` VARCHAR(50) NULL,
`PROFILE_NAME` VARCHAR(100) NULL,
`PACKAGE_NAME` VARCHAR(100) NOT NULL,
`TENANT_ID` INT(11) NULL DEFAULT '0',
`LAST_UPDATED_TIMESTAMP` TIMESTAMP NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE = InnoDB;

@ -50,4 +50,49 @@ FOR EACH ROW
BEGIN
SELECT AD_FEATURE_ID_INC_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
/
CREATE TABLE AD_ENTERPRISE_USER_DEVICE (
ID NUMBER(10) NOT NULL,
ENTERPRISE_ID VARCHAR2(50) NULL,
EMM_USERNAME VARCHAR2(100) NOT NULL,
GOOGLE_USER_ID VARCHAR2(50) NULL,
ANDROID_PLAY_DEVICE_ID VARCHAR2(50) NULL,
EMM_DEVICE_ID VARCHAR2(50) NULL,
TENANT_ID NUMBER(10) DEFAULT '0' NULL,
LAST_UPDATED_TIMESTAMP TIMESTAMP(0) NOT NULL,
PRIMARY KEY (ID)
);
-- Generate ID using sequence and trigger
CREATE SEQUENCE AD_ENTERPRISE_USER_DEVICE_seq START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE TRIGGER AD_ENTERPRISE_USER_DEVICE_seq_tr
BEFORE INSERT ON AD_ENTERPRISE_USER_DEVICE FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT AD_ENTERPRISE_USER_DEVICE_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
/
CREATE TABLE AD_ENTERPRISE_MANAGED_CONFIGS (
ID NUMBER(10) NOT NULL,
MCM_ID VARCHAR2(50) NULL,
PROFILE_NAME VARCHAR2(100) NULL,
PACKAGE_NAME VARCHAR2(100) NOT NULL,
TENANT_ID NUMBER(10) DEFAULT '0' NULL,
LAST_UPDATED_TIMESTAMP TIMESTAMP(0) NOT NULL,
PRIMARY KEY (ID)
) ;
-- Generate ID using sequence and trigger
CREATE SEQUENCE AD_ENTERPRISE_MANAGED_CONFIGS_seq START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE TRIGGER AD_ENTERPRISE_MANAGED_CONFIGS_seq_tr
BEFORE INSERT ON AD_ENTERPRISE_MANAGED_CONFIGS FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT AD_ENTERPRISE_MANAGED_CONFIGS_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
/

@ -30,3 +30,29 @@ CREATE TABLE IF NOT EXISTS AD_FEATURE (
HIDDEN BOOLEAN DEFAULT FALSE,
DESCRIPTION VARCHAR(200) NULL
);
CREATE SEQUENCE AD_ENTERPRISE_USER_DEVICE_seq;
CREATE TABLE IF NOT EXISTS AD_ENTERPRISE_USER_DEVICE (
ID INT NOT NULL DEFAULT NEXTVAL ('AD_ENTERPRISE_USER_DEVICE_seq'),
ENTERPRISE_ID VARCHAR(50) NULL,
EMM_USERNAME VARCHAR(100) NOT NULL,
GOOGLE_USER_ID VARCHAR(50) NULL,
ANDROID_PLAY_DEVICE_ID VARCHAR(50) NULL,
EMM_DEVICE_ID VARCHAR(50) NULL,
TENANT_ID INT NULL DEFAULT '0',
LAST_UPDATED_TIMESTAMP TIMESTAMP(0) NOT NULL,
PRIMARY KEY (ID)
);
CREATE SEQUENCE AD_ENTERPRISE_MANAGED_CONFIGS_seq;
CREATE TABLE IF NOT EXISTS AD_ENTERPRISE_MANAGED_CONFIGS (
ID INT NOT NULL DEFAULT NEXTVAL ('AD_ENTERPRISE_MANAGED_CONFIGS_seq'),
MCM_ID VARCHAR(50) NULL,
PROFILE_NAME VARCHAR(100) NULL,
PACKAGE_NAME VARCHAR(100) NOT NULL,
TENANT_ID INT NULL DEFAULT '0',
LAST_UPDATED_TIMESTAMP TIMESTAMP(0) NOT NULL,
PRIMARY KEY (ID)
) ;

@ -685,40 +685,145 @@
</DeviceStatusTaskConfig>
<DeviceTypePlatformDetails>
<!-- We are strong the SDK Int here-->
<DeviceTypePlatformVersion>
<VersionName>4.0</VersionName>
<VersionName>1</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>4.1</VersionName>
<VersionName>2</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>4.4</VersionName>
<VersionName>3</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>5.0</VersionName>
<VersionName>4</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>6.0</VersionName>
<VersionName>5</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>7.0</VersionName>
<VersionName>6</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>8.0</VersionName>
<VersionName>7</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>9.0</VersionName>
<VersionName>8</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>10.0</VersionName>
<VersionName>9</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>10</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>11</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>12</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>13</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>14</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>15</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>16</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>17</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>18</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>19</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>20</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>21</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>22</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>23</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>24</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>25</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>26</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>27</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>28</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>29</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>30</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>31</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>32</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>33</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>34</VersionName>
</DeviceTypePlatformVersion>
<DeviceTypePlatformVersion>
<VersionName>35</VersionName>
</DeviceTypePlatformVersion>
</DeviceTypePlatformDetails>
</DeviceTypeConfiguration>

@ -12,6 +12,7 @@ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../featur
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.mobile.android_${feature.version}/apis/admin--Android-Mutual-SSL-Configuration-Management.xml,target:${installFolder}/../../deployment/server/synapse-configs/default/api/admin--Android-Mutual-SSL-Configuration-Management.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.mobile.android_${feature.version}/apis/admin--Android-Mutual-SSL-Device-Management.xml,target:${installFolder}/../../deployment/server/synapse-configs/default/api/admin--Android-Mutual-SSL-Device-Management.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.mobile.android_${feature.version}/apis/admin--Android-Mutual-SSL-Event-Receiver.xml,target:${installFolder}/../../deployment/server/synapse-configs/default/api/admin--Android-Mutual-SSL-Event-Receiver.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.mobile.android_${feature.version}/conf/android-dbconfig.xml,target:${installFolder}/../../conf/android-dbconfig.xml,overwrite:true);\
instructions.unconfigure = \
org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/webapps/mdm-android-agent.war);\

Loading…
Cancel
Save