mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Add Windows enterprise app installation support for publisher and store
This commit is contained in:
parent
24d0e7b392
commit
8238f7dd22
@ -17,5 +17,5 @@
|
||||
package org.wso2.carbon.device.application.mgt.common;
|
||||
|
||||
public enum DeviceTypes {
|
||||
ANDROID, IOS
|
||||
ANDROID, IOS, WINDOWS
|
||||
}
|
||||
|
||||
@ -31,6 +31,10 @@ public class Application {
|
||||
required = true)
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(name = "installerName",
|
||||
value = "Application Installer Name")
|
||||
private String installerName;
|
||||
|
||||
@ApiModelProperty(name = "description",
|
||||
value = "Description of the application",
|
||||
required = true)
|
||||
@ -173,4 +177,8 @@ public class Application {
|
||||
public boolean isAndroidEnterpriseApp() { return isAndroidEnterpriseApp; }
|
||||
|
||||
public void setAndroidEnterpriseApp(boolean androidEnterpriseApp) { isAndroidEnterpriseApp = androidEnterpriseApp; }
|
||||
|
||||
public String getInstallerName() { return installerName; }
|
||||
|
||||
public void setInstallerName(String installerName) { this.installerName = installerName; }
|
||||
}
|
||||
|
||||
@ -87,6 +87,10 @@ public class ApplicationRelease {
|
||||
value = "Application Rating")
|
||||
private double rating;
|
||||
|
||||
@ApiModelProperty(name = "packageName",
|
||||
value = "package name of the application")
|
||||
private String packageName;
|
||||
|
||||
public String getReleaseType() {
|
||||
return releaseType;
|
||||
}
|
||||
@ -162,4 +166,8 @@ public class ApplicationRelease {
|
||||
public List<String> getScreenshots() { return screenshots; }
|
||||
|
||||
public void setScreenshots(List<String> screenshots) { this.screenshots = screenshots; }
|
||||
|
||||
public String getPackageName() { return packageName; }
|
||||
|
||||
public void setPackageName(String packageName) { this.packageName = packageName; }
|
||||
}
|
||||
|
||||
@ -281,6 +281,16 @@ public interface ApplicationManager {
|
||||
|
||||
String getInstallableLifecycleState() throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* Check if there are subscription devices for operations
|
||||
*
|
||||
* @param operationId Id of the operation
|
||||
* @param deviceId deviceId of the relevant device
|
||||
* @return boolean value either true or false according to the situation
|
||||
* @throws ApplicationManagementException
|
||||
*/
|
||||
boolean checkSubDeviceIdsForOperations(int operationId, int deviceId) throws ApplicationManagementException;
|
||||
|
||||
void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException;
|
||||
|
||||
|
||||
|
||||
@ -60,6 +60,14 @@ public class EntAppReleaseWrapper {
|
||||
@NotNull
|
||||
private String supportedOsVersions;
|
||||
|
||||
@ApiModelProperty(name = "version",
|
||||
value = "Version number of the applications installer specifically for windows")
|
||||
private String version;
|
||||
|
||||
@ApiModelProperty(name = "packageName",
|
||||
value = "PackageName of the application installer specifically for windows")
|
||||
private String packageName;
|
||||
|
||||
public String getReleaseType() {
|
||||
return releaseType;
|
||||
}
|
||||
@ -99,4 +107,20 @@ public class EntAppReleaseWrapper {
|
||||
public String getSupportedOsVersions() { return supportedOsVersions; }
|
||||
|
||||
public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; }
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,6 +141,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
}
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(applicationWrapper);
|
||||
|
||||
//uploading application artifacts
|
||||
ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts(
|
||||
applicationDTO.getApplicationReleaseDTOs().get(0), applicationArtifact,
|
||||
@ -338,9 +339,25 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream());
|
||||
applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName());
|
||||
try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) {
|
||||
ApplicationInstaller applicationInstaller = applicationStorageManager
|
||||
.getAppInstallerData(binary, deviceType);
|
||||
String packagename = applicationInstaller.getPackageName();
|
||||
ApplicationInstaller applicationInstaller = null;
|
||||
String packagename;
|
||||
if (!DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
|
||||
applicationInstaller = applicationStorageManager.getAppInstallerData(binary, deviceType);
|
||||
packagename = applicationInstaller.getPackageName();
|
||||
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
|
||||
applicationReleaseDTO.setPackageName(packagename);
|
||||
} else {
|
||||
String windowsInstallerName = applicationArtifact.getInstallerName();
|
||||
String extension = windowsInstallerName.substring(windowsInstallerName.lastIndexOf(".") + 1);
|
||||
if (!extension.equalsIgnoreCase(Constants.MSI) &&
|
||||
!extension.equalsIgnoreCase(Constants.APPX)) {
|
||||
String msg = "Application Type doesn't match with supporting application types of " +
|
||||
deviceType + "platform which are APPX and MSI";
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
packagename = applicationReleaseDTO.getPackageName();
|
||||
}
|
||||
|
||||
try {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
@ -354,8 +371,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
applicationReleaseDTO.setVersion(applicationInstaller.getVersion());
|
||||
applicationReleaseDTO.setPackageName(packagename);
|
||||
String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content));
|
||||
if (md5OfApp == null) {
|
||||
String msg = "Error occurred while md5sum value retrieving process: application UUID "
|
||||
@ -1012,6 +1027,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
|
||||
ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts(
|
||||
APIUtil.releaseWrapperToReleaseDTO(entAppReleaseWrapper), applicationArtifact, deviceType.getName(),
|
||||
tenantId, true);
|
||||
@ -2680,7 +2696,12 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
if (!StringUtils.isEmpty(entAppReleaseWrapper.getMetaData())) {
|
||||
applicationReleaseDTO.get().setMetaData(entAppReleaseWrapper.getMetaData());
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(entAppReleaseWrapper.getVersion())) { // Updating version
|
||||
applicationReleaseDTO.get().setVersion(entAppReleaseWrapper.getVersion());
|
||||
}
|
||||
if (!StringUtils.isEmpty(entAppReleaseWrapper.getPackageName())) { // Updating packageName
|
||||
applicationReleaseDTO.get().setPackageName(entAppReleaseWrapper.getPackageName());
|
||||
}
|
||||
if (!StringUtils.isEmpty(applicationArtifact.getInstallerName())
|
||||
&& applicationArtifact.getInstallerStream() != null) {
|
||||
DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
|
||||
@ -3114,6 +3135,17 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
unrestrictedRoles = applicationWrapper.getUnrestrictedRoles();
|
||||
|
||||
//Validating the version number and the packageName of the Windows applications
|
||||
if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(applicationWrapper.getDeviceType())) {
|
||||
if (applicationWrapper.getEntAppReleaseWrappers().get(0).getVersion() == null ||
|
||||
applicationWrapper.getEntAppReleaseWrappers().get(0).getPackageName() == null) {
|
||||
String msg = "Application Version number or/and PackageName both are required only when the app type is " +
|
||||
applicationWrapper.getDeviceType() + " platform type";
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
} else if (param instanceof WebAppWrapper) {
|
||||
WebAppWrapper webAppWrapper = (WebAppWrapper) param;
|
||||
appName = webAppWrapper.getName();
|
||||
@ -3326,6 +3358,15 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
//Validating the version number and the packageName of the Windows new applications releases
|
||||
if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
|
||||
if (entAppReleaseWrapper.get().getVersion() == null || entAppReleaseWrapper.get().getPackageName() == null) {
|
||||
String msg = "Application Version number or/and PackageName..both are required only when the app type is " +
|
||||
deviceType + " platform type";
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
} else if (param instanceof WebAppReleaseWrapper) {
|
||||
WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param;
|
||||
UrlValidator urlValidator = new UrlValidator();
|
||||
@ -3414,18 +3455,31 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkSubDeviceIdsForOperations(int operationId, int deviceId) throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
try {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
List<Integer> deviceSubIds = subscriptionDAO.getDeviceSubIdsForOperation(operationId, deviceId, tenantId);
|
||||
if (deviceSubIds.isEmpty() || deviceSubIds == null) {
|
||||
return false;
|
||||
}
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
String msg = "Error occurred while getting the device sub ids for the operations";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
try {
|
||||
ConnectionManagerUtil.beginDBTransaction();
|
||||
List<Integer> deviceSubIds = subscriptionDAO.getDeviceSubIdsForOperation(operationId, deviceId, tenantId);
|
||||
if (deviceSubIds.isEmpty()){
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Couldn't find device subscription for operation id " + operationId;
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
if (!subscriptionDAO.updateDeviceSubStatus(deviceId, deviceSubIds, status, tenantId)){
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Didn't update an any app subscription of device for operation Id: " + operationId;
|
||||
|
||||
@ -82,6 +82,7 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
|
||||
import org.wso2.carbon.device.mgt.core.util.MDMAndroidOperationUtil;
|
||||
import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil;
|
||||
import org.wso2.carbon.device.mgt.core.util.MDMWindowsOperationUtil;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||
@ -1022,6 +1023,18 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
} else if (DeviceTypes.WINDOWS.toString().equalsIgnoreCase(deviceType)) {
|
||||
app.setType(mobileAppType);
|
||||
app.setIdentifier(application.getPackageName());
|
||||
app.setMetaData(application.getApplicationReleases().get(0).getMetaData());
|
||||
app.setName(application.getInstallerName());
|
||||
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
|
||||
return MDMWindowsOperationUtil.createInstallAppOperation(app);
|
||||
} else {
|
||||
String msg = "Invalid Action is found. Action: " + action;
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
} else {
|
||||
String msg = "Invalid device type is found. Device Type: " + deviceType;
|
||||
log.error(msg);
|
||||
|
||||
@ -304,6 +304,10 @@ public class APIUtil {
|
||||
applicationReleaseDTO.setIsSharedWithAllTenants(entAppReleaseWrapper.getIsSharedWithAllTenants());
|
||||
applicationReleaseDTO.setMetaData(entAppReleaseWrapper.getMetaData());
|
||||
applicationReleaseDTO.setSupportedOsVersions(entAppReleaseWrapper.getSupportedOsVersions());
|
||||
//Setting version number value specifically for windows type and in an instance of android and ios it will be null
|
||||
applicationReleaseDTO.setVersion(entAppReleaseWrapper.getVersion());
|
||||
//Setting package name value specifically for windows type and in an instance of android and ios it will be null
|
||||
applicationReleaseDTO.setPackageName(entAppReleaseWrapper.getPackageName());
|
||||
} else if (param instanceof WebAppReleaseWrapper){
|
||||
WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param;
|
||||
applicationReleaseDTO.setDescription(webAppReleaseWrapper.getDescription());
|
||||
@ -358,6 +362,7 @@ public class APIUtil {
|
||||
application.setTags(applicationDTO.getTags());
|
||||
application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles());
|
||||
application.setRating(applicationDTO.getAppRating());
|
||||
application.setInstallerName(applicationDTO.getApplicationReleaseDTOs().get(0).getInstallerName());
|
||||
List<ApplicationRelease> applicationReleases = new ArrayList<>();
|
||||
if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories()
|
||||
.contains("GooglePlaySyncedApp")) {
|
||||
@ -384,6 +389,7 @@ public class APIUtil {
|
||||
|
||||
applicationRelease.setDescription(applicationReleaseDTO.getDescription());
|
||||
applicationRelease.setVersion(applicationReleaseDTO.getVersion());
|
||||
applicationRelease.setPackageName(applicationReleaseDTO.getPackageName());
|
||||
applicationRelease.setUuid(applicationReleaseDTO.getUuid());
|
||||
applicationRelease.setReleaseType(applicationReleaseDTO.getReleaseType());
|
||||
applicationRelease.setPrice(applicationReleaseDTO.getPrice());
|
||||
|
||||
@ -65,6 +65,10 @@ public class Constants {
|
||||
public static final String SUBSCRIBED = "SUBSCRIBED";
|
||||
public static final String UNSUBSCRIBED = "UNSUBSCRIBED";
|
||||
|
||||
//App type constants related to window device type
|
||||
public static final String MSI = "MSI";
|
||||
public static final String APPX = "APPX";
|
||||
|
||||
private static final Map<String, String> AGENT_DATA = new HashMap<>();
|
||||
static {
|
||||
AGENT_DATA.put("android", "android-agent.apk");
|
||||
|
||||
@ -373,6 +373,10 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
|
||||
log.error("ApplicationDTO Creation Failed");
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
} catch (BadRequestException e) {
|
||||
String msg = "Found incompatible payload with enterprise app release creating request.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while creating the application";
|
||||
log.error(msg, e);
|
||||
|
||||
@ -85,6 +85,12 @@
|
||||
}
|
||||
},
|
||||
"deviceTypes": {
|
||||
"mobileTypes": ["android", "ios"]
|
||||
"mobileTypes": ["android", "ios", "windows"]
|
||||
},
|
||||
"windowsDeviceType": {
|
||||
"appType": ["msi", "appx"]
|
||||
},
|
||||
"windowsAppxMsiKeyValueForMetaData": {
|
||||
"metaKeyArray": ["Package_Url", "Dependency_Package_Url", "Certificate_Hash", "Encoded_Cert_Content", "Package_Family_Name", "Product_Id", "Content_Uri", "File_Hash"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ class NewAppDetailsForm extends React.Component {
|
||||
categories: [],
|
||||
tags: [],
|
||||
deviceTypes: [],
|
||||
selectedValue: null,
|
||||
fetching: false,
|
||||
roleSearchValue: [],
|
||||
unrestrictedRoles: [],
|
||||
@ -312,12 +313,33 @@ class NewAppDetailsForm extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
// Event handler for selecting the device type
|
||||
handleSelect = event => {
|
||||
this.setState({
|
||||
selectedValue: event,
|
||||
});
|
||||
if (this.props.selectedValueHandler) {
|
||||
this.props.selectedValueHandler(event);
|
||||
}
|
||||
};
|
||||
|
||||
// Event handler for selecting the windows app type
|
||||
handleSelectForAppType = event => {
|
||||
if (this.props.selectedAppTypeHandler) {
|
||||
this.props.selectedAppTypeHandler(event);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const config = this.props.context;
|
||||
// Windows installation app types
|
||||
const appTypes = config.windowsDeviceType.appType;
|
||||
const { formConfig } = this.props;
|
||||
const {
|
||||
categories,
|
||||
tags,
|
||||
deviceTypes,
|
||||
selectedValue,
|
||||
fetching,
|
||||
unrestrictedRoles,
|
||||
} = this.state;
|
||||
@ -358,6 +380,7 @@ class NewAppDetailsForm extends React.Component {
|
||||
<Select
|
||||
style={{ width: '100%' }}
|
||||
placeholder="select device type"
|
||||
onSelect={this.handleSelect.bind(this)}
|
||||
>
|
||||
{deviceTypes.map(deviceType => {
|
||||
return (
|
||||
@ -396,6 +419,31 @@ class NewAppDetailsForm extends React.Component {
|
||||
})(<Input placeholder="ex: Lorem App" />)}
|
||||
</Form.Item>
|
||||
|
||||
{/* App Type only shown for windows device types for enterprise apps */}
|
||||
{selectedValue === 'windows' &&
|
||||
this.props.formConfig.installationType === 'ENTERPRISE' && (
|
||||
<Form.Item {...formItemLayout} label="App Type">
|
||||
{getFieldDecorator('appType', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please select app type',
|
||||
},
|
||||
],
|
||||
})(
|
||||
<Select
|
||||
style={{ width: '100%' }}
|
||||
placeholder="select application type"
|
||||
onSelect={this.handleSelectForAppType}
|
||||
>
|
||||
{appTypes.map(appType => {
|
||||
return <Option key={appType}>{appType}</Option>;
|
||||
})}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* description*/}
|
||||
<Form.Item {...formItemLayout} label="Description">
|
||||
{getFieldDecorator('description', {
|
||||
|
||||
@ -33,6 +33,7 @@ import {
|
||||
} from 'antd';
|
||||
import '@babel/polyfill';
|
||||
import Authorized from '../../../../../../../../components/Authorized/Authorized';
|
||||
import { withConfigContext } from '../../../../../../../../components/ConfigContext';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
@ -59,6 +60,12 @@ function getBase64(file) {
|
||||
});
|
||||
}
|
||||
|
||||
// function for access the full name of the binary file using the installation path
|
||||
function extractBinaryFileName(installationPath) {
|
||||
let UploadedBinaryName = installationPath.split('/');
|
||||
return UploadedBinaryName[UploadedBinaryName.length - 1];
|
||||
}
|
||||
|
||||
class NewAppUploadForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -77,6 +84,7 @@ class NewAppUploadForm extends React.Component {
|
||||
osVersionsHelperText: '',
|
||||
osVersionsValidateStatus: 'validating',
|
||||
metaData: [],
|
||||
appType: null,
|
||||
};
|
||||
this.lowerOsVersion = null;
|
||||
this.upperOsVersion = null;
|
||||
@ -93,6 +101,8 @@ class NewAppUploadForm extends React.Component {
|
||||
e.preventDefault();
|
||||
const { formConfig } = this.props;
|
||||
const { specificElements } = formConfig;
|
||||
let windowsAppTypeMetaArray = [];
|
||||
let metaValue = [];
|
||||
|
||||
this.props.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
@ -107,6 +117,19 @@ class NewAppUploadForm extends React.Component {
|
||||
releaseType,
|
||||
} = values;
|
||||
|
||||
/**
|
||||
* To save the metaData value that receive from
|
||||
* metaData UI In an windows app type creation
|
||||
*/
|
||||
if (
|
||||
((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows') ||
|
||||
this.props.deviceType === 'windows') &&
|
||||
this.state.metaData.length !== 0
|
||||
) {
|
||||
metaValue = [...this.state.metaData];
|
||||
}
|
||||
|
||||
// add release data
|
||||
const release = {
|
||||
description: releaseDescription,
|
||||
@ -116,6 +139,90 @@ class NewAppUploadForm extends React.Component {
|
||||
releaseType: releaseType,
|
||||
};
|
||||
|
||||
const data = new FormData();
|
||||
const config = this.props.context;
|
||||
// Accessing the Meta Key value for windows device type from the config.json file
|
||||
const metaKeyValues =
|
||||
config.windowsAppxMsiKeyValueForMetaData.metaKeyArray;
|
||||
|
||||
/*
|
||||
Setting up the app type specific values to the
|
||||
metaData state field and Setting up the version
|
||||
and the packageName for windows type
|
||||
*/
|
||||
if (
|
||||
(this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows') ||
|
||||
this.props.deviceType === 'windows'
|
||||
) {
|
||||
// Setting up the version and packageName
|
||||
release.version = values.version;
|
||||
release.packageName = values.packageName;
|
||||
// setting the metaData value for appx type
|
||||
if (
|
||||
this.props.selectedAppType === 'appx' ||
|
||||
this.state.appType === 'appx'
|
||||
) {
|
||||
windowsAppTypeMetaArray = [
|
||||
{
|
||||
key: metaKeyValues[0],
|
||||
value: values.packageUrl,
|
||||
},
|
||||
{
|
||||
key: metaKeyValues[1],
|
||||
value: values.dependencyPackageUrl,
|
||||
},
|
||||
{
|
||||
key: metaKeyValues[2],
|
||||
value: values.certificateHash,
|
||||
},
|
||||
{
|
||||
key: metaKeyValues[3],
|
||||
value: values.encodedCertContent,
|
||||
},
|
||||
{
|
||||
key: metaKeyValues[4],
|
||||
value: values.packageName,
|
||||
},
|
||||
];
|
||||
windowsAppTypeMetaArray = [
|
||||
...windowsAppTypeMetaArray,
|
||||
...metaValue,
|
||||
];
|
||||
} else if (
|
||||
this.props.selectedAppType === 'msi' ||
|
||||
this.state.appType === 'msi'
|
||||
) {
|
||||
windowsAppTypeMetaArray = [
|
||||
{
|
||||
key: metaKeyValues[5],
|
||||
value: values.productId,
|
||||
},
|
||||
{
|
||||
key: metaKeyValues[6],
|
||||
value: values.contentUri,
|
||||
},
|
||||
{
|
||||
key: metaKeyValues[7],
|
||||
value: values.fileHash,
|
||||
},
|
||||
];
|
||||
windowsAppTypeMetaArray = [
|
||||
...windowsAppTypeMetaArray,
|
||||
...metaValue,
|
||||
];
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
metaData: windowsAppTypeMetaArray,
|
||||
},
|
||||
() => {
|
||||
release.metaData = JSON.stringify(this.state.metaData);
|
||||
this.props.onSuccessReleaseData({ data, release });
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (specificElements.hasOwnProperty('version')) {
|
||||
release.version = values.version;
|
||||
}
|
||||
@ -126,7 +233,6 @@ class NewAppUploadForm extends React.Component {
|
||||
release.packageName = values.packageName;
|
||||
}
|
||||
|
||||
const data = new FormData();
|
||||
let isFormValid = true; // flag to check if this form is valid
|
||||
|
||||
if (
|
||||
@ -187,7 +293,16 @@ class NewAppUploadForm extends React.Component {
|
||||
if (specificElements.hasOwnProperty('binaryFile')) {
|
||||
data.append('binaryFile', binaryFile[0].originFileObj);
|
||||
}
|
||||
this.props.onSuccessReleaseData({ data, release });
|
||||
// Condition to check is it not an Enterprise windows app creation or release
|
||||
if (
|
||||
!(
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.formConfig.installationType === 'ENTERPRISE'
|
||||
) &&
|
||||
this.props.deviceType !== 'windows'
|
||||
) {
|
||||
this.props.onSuccessReleaseData({ data, release });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -203,13 +318,44 @@ class NewAppUploadForm extends React.Component {
|
||||
icons: fileList,
|
||||
});
|
||||
};
|
||||
|
||||
handleBinaryFileChange = ({ fileList }) => {
|
||||
let validity = true;
|
||||
// To set the app type of windows by using the binary file in an new app release
|
||||
if (this.props.formConfig.isNewRelease && fileList.length !== 0) {
|
||||
let firstUploadedBinaryFileName = extractBinaryFileName(
|
||||
this.props.uploadedInstalltionAppType,
|
||||
);
|
||||
let FirstFileExtension = firstUploadedBinaryFileName.substr(
|
||||
firstUploadedBinaryFileName.lastIndexOf('.') + 1,
|
||||
);
|
||||
let LastFileExtension = fileList[0].name.substr(
|
||||
fileList[0].name.lastIndexOf('.') + 1,
|
||||
);
|
||||
if (FirstFileExtension !== LastFileExtension) {
|
||||
validity = false;
|
||||
} else if (LastFileExtension === 'msi' || LastFileExtension === 'appx') {
|
||||
this.setState({
|
||||
appType: LastFileExtension,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (fileList.length === 1) {
|
||||
this.setState({
|
||||
binaryFileHelperText: '',
|
||||
});
|
||||
}
|
||||
this.setState({ binaryFiles: fileList });
|
||||
|
||||
if (validity) {
|
||||
this.setState({
|
||||
binaryFiles: fileList,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
binaryFileHelperText: 'Upload Correct Binary File extension',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleScreenshotChange = ({ fileList }) => {
|
||||
@ -266,6 +412,7 @@ class NewAppUploadForm extends React.Component {
|
||||
render() {
|
||||
const { formConfig, supportedOsVersions } = this.props;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const config = this.props.context;
|
||||
const {
|
||||
icons,
|
||||
screenshots,
|
||||
@ -399,7 +546,12 @@ class NewAppUploadForm extends React.Component {
|
||||
</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
{formConfig.specificElements.hasOwnProperty('packageName') && (
|
||||
|
||||
{/* Package Name field for windows device type and other specific scene using it */}
|
||||
{(formConfig.specificElements.hasOwnProperty('packageName') ||
|
||||
(this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows') ||
|
||||
this.props.deviceType === 'windows') && (
|
||||
<Form.Item {...formItemLayout} label="Package Name">
|
||||
{getFieldDecorator('packageName', {
|
||||
rules: [
|
||||
@ -425,7 +577,11 @@ class NewAppUploadForm extends React.Component {
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{formConfig.specificElements.hasOwnProperty('version') && (
|
||||
{/* Version field for windows device type and other specific scene using it */}
|
||||
{(formConfig.specificElements.hasOwnProperty('version') ||
|
||||
(this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows') ||
|
||||
this.props.deviceType === 'windows') && (
|
||||
<Form.Item {...formItemLayout} label="Version">
|
||||
{getFieldDecorator('version', {
|
||||
rules: [
|
||||
@ -438,6 +594,127 @@ class NewAppUploadForm extends React.Component {
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* Windows Appx App Type Fields */}
|
||||
{/* For Windows appx app type only -> Package Url */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'appx') ||
|
||||
this.state.appType === 'appx') && (
|
||||
<Form.Item {...formItemLayout} label="Package Url">
|
||||
{getFieldDecorator('packageUrl', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the package url',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Package Url" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* For Windows appx app type only -> Dependency Package Url */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'appx') ||
|
||||
this.state.appType === 'appx') && (
|
||||
<Form.Item {...formItemLayout} label="Dependency Package Url">
|
||||
{getFieldDecorator('dependencyPackageUrl', {})(
|
||||
<Input placeholder="Dependency Package Url" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* For Windows appx app type only -> Certificate Hash */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'appx') ||
|
||||
this.state.appType === 'appx') && (
|
||||
<Form.Item {...formItemLayout} label="Certificate Hash">
|
||||
{getFieldDecorator('certificateHash', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the certificate hash',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Certificate Hash" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* For Windows appx app type only -> Encoded Certificate Content */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'appx') ||
|
||||
this.state.appType === 'appx') && (
|
||||
<Form.Item {...formItemLayout} label="Encoded Cert Content">
|
||||
{getFieldDecorator('encodedCertContent', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Give the encoded cert content',
|
||||
},
|
||||
],
|
||||
})(
|
||||
<TextArea
|
||||
placeholder="Enter a encoded certificate content"
|
||||
rows={5}
|
||||
/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* Windows MSI App Type Fields */}
|
||||
{/* For Windows msi app type only -> Product Id */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'msi') ||
|
||||
this.state.appType === 'msi') && (
|
||||
<Form.Item {...formItemLayout} label="Product Id">
|
||||
{getFieldDecorator('productId', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the product id',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Product Id" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* For Windows msi app type only -> Content URI */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'msi') ||
|
||||
this.state.appType === 'msi') && (
|
||||
<Form.Item {...formItemLayout} label="Content URI">
|
||||
{getFieldDecorator('contentUri', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the content uri',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Content Uri" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* For Windows msi app type only -> File Hash */}
|
||||
{((this.props.formConfig.installationType === 'ENTERPRISE' &&
|
||||
this.props.selectedValue === 'windows' &&
|
||||
this.props.selectedAppType === 'msi') ||
|
||||
this.state.appType === 'msi') && (
|
||||
<Form.Item {...formItemLayout} label="File Hash">
|
||||
{getFieldDecorator('fileHash', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the file hash',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="File Hash" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
<Form.Item {...formItemLayout} label="Release Type">
|
||||
{getFieldDecorator('releaseType', {
|
||||
rules: [
|
||||
@ -547,49 +824,60 @@ class NewAppUploadForm extends React.Component {
|
||||
{getFieldDecorator('meta', {})(
|
||||
<div>
|
||||
{metaData.map((data, index) => {
|
||||
return (
|
||||
<InputGroup key={index}>
|
||||
<Row gutter={8}>
|
||||
<Col span={5}>
|
||||
<Input
|
||||
placeholder="key"
|
||||
value={data.key}
|
||||
onChange={e => {
|
||||
metaData[index].key = e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Input
|
||||
placeholder="value"
|
||||
value={data.value}
|
||||
onChange={e => {
|
||||
metaData[index].value = e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<Button
|
||||
type="dashed"
|
||||
shape="circle"
|
||||
icon={<MinusOutlined />}
|
||||
onClick={() => {
|
||||
metaData.splice(index, 1);
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</InputGroup>
|
||||
);
|
||||
/*
|
||||
Exclude showing the values related to
|
||||
windows app type variables in meta Data UI
|
||||
*/
|
||||
if (
|
||||
!config.windowsAppxMsiKeyValueForMetaData.metaKeyArray.includes(
|
||||
data.key,
|
||||
)
|
||||
) {
|
||||
return (
|
||||
<InputGroup key={index}>
|
||||
<Row gutter={8}>
|
||||
<Col span={5}>
|
||||
<Input
|
||||
placeholder="key"
|
||||
value={data.key}
|
||||
onChange={e => {
|
||||
metaData[index].key = e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Input
|
||||
placeholder="value"
|
||||
value={data.value}
|
||||
onChange={e => {
|
||||
metaData[index].value =
|
||||
e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<Button
|
||||
type="dashed"
|
||||
shape="circle"
|
||||
icon={<MinusOutlined />}
|
||||
onClick={() => {
|
||||
metaData.splice(index, 1);
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</InputGroup>
|
||||
);
|
||||
}
|
||||
})}
|
||||
<Button
|
||||
type="dashed"
|
||||
@ -633,4 +921,6 @@ class NewAppUploadForm extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default Form.create({ name: 'app-upload-form' })(NewAppUploadForm);
|
||||
export default withConfigContext(
|
||||
Form.create({ name: 'app-upload-form' })(NewAppUploadForm),
|
||||
);
|
||||
|
||||
@ -44,6 +44,8 @@ class AddNewAppFormComponent extends React.Component {
|
||||
release: null,
|
||||
isError: false,
|
||||
deviceType: null,
|
||||
selectedValue: null,
|
||||
selectedAppType: null,
|
||||
supportedOsVersions: [],
|
||||
errorText: '',
|
||||
forbiddenErrors: {
|
||||
@ -157,6 +159,20 @@ class AddNewAppFormComponent extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
// For passing the device type as the prop for other component
|
||||
selectedValueHandler = selectedValue => {
|
||||
this.setState({
|
||||
selectedValue,
|
||||
});
|
||||
};
|
||||
|
||||
// For passing the app type as the prop for other component
|
||||
selectedAppTypeHandler = selectedAppType => {
|
||||
this.setState({
|
||||
selectedAppType,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
loading,
|
||||
@ -164,6 +180,8 @@ class AddNewAppFormComponent extends React.Component {
|
||||
isError,
|
||||
supportedOsVersions,
|
||||
errorText,
|
||||
selectedValue,
|
||||
selectedAppType,
|
||||
} = this.state;
|
||||
const { formConfig } = this.props;
|
||||
return (
|
||||
@ -180,18 +198,21 @@ class AddNewAppFormComponent extends React.Component {
|
||||
<div style={{ display: current === 0 ? 'unset' : 'none' }}>
|
||||
<NewAppDetailsForm
|
||||
formConfig={formConfig}
|
||||
selectedValueHandler={this.selectedValueHandler}
|
||||
selectedAppTypeHandler={this.selectedAppTypeHandler}
|
||||
onSuccessApplicationData={this.onSuccessApplicationData}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: current === 1 ? 'unset' : 'none' }}>
|
||||
<NewAppUploadForm
|
||||
formConfig={formConfig}
|
||||
selectedValue={selectedValue}
|
||||
selectedAppType={selectedAppType}
|
||||
supportedOsVersions={supportedOsVersions}
|
||||
onSuccessReleaseData={this.onSuccessReleaseData}
|
||||
onClickBackButton={this.onClickBackButton}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: current === 2 ? 'unset' : 'none' }}>
|
||||
{!isError && (
|
||||
<Result
|
||||
|
||||
@ -27,6 +27,7 @@ import { handleApiError } from '../../../../../../services/utils/errorHandler';
|
||||
import NewAppUploadForm from '../../../AddNewApp/components/AddNewAppForm/components/NewAppUploadForm';
|
||||
|
||||
const formConfig = {
|
||||
isNewRelease: true,
|
||||
specificElements: {
|
||||
binaryFile: {
|
||||
required: true,
|
||||
@ -163,6 +164,11 @@ class AddNewReleaseFormComponent extends React.Component {
|
||||
<NewAppUploadForm
|
||||
forbiddenErrors={forbiddenErrors}
|
||||
formConfig={formConfig}
|
||||
deviceType={this.props.deviceType}
|
||||
// Takes the first upload app type installation path
|
||||
uploadedInstalltionAppType={
|
||||
this.props.location.state.appDetails.installerPath
|
||||
}
|
||||
supportedOsVersions={supportedOsVersions}
|
||||
onSuccessReleaseData={this.onSuccessReleaseData}
|
||||
onClickBackButton={this.onClickBackButton}
|
||||
|
||||
@ -783,6 +783,7 @@ class AppDetailsDrawer extends React.Component {
|
||||
to={{
|
||||
pathname: `/publisher/apps/${app.deviceType}/${app.id}/add-release`,
|
||||
state: {
|
||||
appDetails: app.applicationReleases[0],
|
||||
fullAppDetails: app.applicationReleases,
|
||||
},
|
||||
}}
|
||||
|
||||
@ -65,6 +65,12 @@ function getBase64(file) {
|
||||
reader.onerror = error => reject(error);
|
||||
});
|
||||
}
|
||||
// function for access the name of the binary file using the installation path
|
||||
function extractBinaryFileName(installationPath) {
|
||||
let UploadedBinaryName = installationPath.split('/');
|
||||
let binaryFileName = UploadedBinaryName[UploadedBinaryName.length - 1];
|
||||
return binaryFileName.substr(binaryFileName.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
class EditReleaseModal extends React.Component {
|
||||
// To add subscription type & tenancy sharing, refer https://gitlab.com/entgra/carbon-device-mgt/merge_requests/331
|
||||
@ -156,7 +162,6 @@ class EditReleaseModal extends React.Component {
|
||||
const { formConfig } = this.state;
|
||||
const { specificElements } = formConfig;
|
||||
let metaData = [];
|
||||
|
||||
try {
|
||||
metaData = JSON.parse(release.metaData);
|
||||
} catch (e) {
|
||||
@ -185,7 +190,23 @@ class EditReleaseModal extends React.Component {
|
||||
},
|
||||
});
|
||||
}
|
||||
if (specificElements.hasOwnProperty('version')) {
|
||||
// Showing the packageName value in the edit form UI
|
||||
if (
|
||||
formConfig.specificElements.hasOwnProperty('packageName') ||
|
||||
(this.props.type === 'ENTERPRISE' && this.props.deviceType === 'windows')
|
||||
) {
|
||||
this.props.form.setFields({
|
||||
packageName: {
|
||||
value: release.packageName,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Showing the version value in the edit form UI
|
||||
if (
|
||||
formConfig.specificElements.hasOwnProperty('version') ||
|
||||
(this.props.type === 'ENTERPRISE' && this.props.deviceType === 'windows')
|
||||
) {
|
||||
this.props.form.setFields({
|
||||
version: {
|
||||
value: release.version,
|
||||
@ -201,14 +222,6 @@ class EditReleaseModal extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
if (specificElements.hasOwnProperty('packageName')) {
|
||||
this.props.form.setFields({
|
||||
packageName: {
|
||||
value: release.packageName,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
visible: true,
|
||||
metaData,
|
||||
@ -248,6 +261,10 @@ class EditReleaseModal extends React.Component {
|
||||
|
||||
const { formConfig } = this.state;
|
||||
const { specificElements } = formConfig;
|
||||
// Accessing the extension type of the current uploaded binary file
|
||||
const appTypeExtension = extractBinaryFileName(
|
||||
this.props.release.installerPath,
|
||||
);
|
||||
|
||||
this.props.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
@ -280,10 +297,38 @@ class EditReleaseModal extends React.Component {
|
||||
data.append('binaryFile', binaryFiles[0].originFileObj);
|
||||
}
|
||||
|
||||
if (specificElements.hasOwnProperty('version')) {
|
||||
if (
|
||||
specificElements.hasOwnProperty('version') ||
|
||||
(this.props.type === 'ENTERPRISE' &&
|
||||
this.props.deviceType === 'windows')
|
||||
) {
|
||||
release.version = values.version;
|
||||
}
|
||||
|
||||
// Accessing the Meta Key value for windows device type from the config.json file
|
||||
const metaKeyValues =
|
||||
config.windowsAppxMsiKeyValueForMetaData.metaKeyArray;
|
||||
|
||||
if (
|
||||
specificElements.hasOwnProperty('packageName') ||
|
||||
(this.props.type === 'ENTERPRISE' &&
|
||||
this.props.deviceType === 'windows')
|
||||
) {
|
||||
release.packageName = values.packageName;
|
||||
// Setting up the packageName to the package_Family_Name key in an appx app type instance
|
||||
if (appTypeExtension === config.windowsDeviceType.appType[1]) {
|
||||
let metaDataArray = this.state.metaData;
|
||||
let filterMetaArray = metaDataArray.filter(
|
||||
obj => obj.key !== metaKeyValues[4],
|
||||
);
|
||||
filterMetaArray.push({
|
||||
key: metaKeyValues[4],
|
||||
value: values.packageName,
|
||||
});
|
||||
release.metaData = JSON.stringify(filterMetaArray);
|
||||
}
|
||||
}
|
||||
|
||||
if (specificElements.hasOwnProperty('url')) {
|
||||
release.url = values.url;
|
||||
}
|
||||
@ -335,7 +380,6 @@ class EditReleaseModal extends React.Component {
|
||||
message: 'Done!',
|
||||
description: 'Saved!',
|
||||
});
|
||||
// console.log(updatedRelease);
|
||||
this.props.updateRelease(updatedRelease);
|
||||
}
|
||||
})
|
||||
@ -463,7 +507,6 @@ class EditReleaseModal extends React.Component {
|
||||
)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{formConfig.specificElements.hasOwnProperty('url') && (
|
||||
<Form.Item {...formItemLayout} label="URL">
|
||||
{getFieldDecorator('url', {
|
||||
@ -477,19 +520,6 @@ class EditReleaseModal extends React.Component {
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{formConfig.specificElements.hasOwnProperty('version') && (
|
||||
<Form.Item {...formItemLayout} label="Version">
|
||||
{getFieldDecorator('version', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the version',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Version" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
<Form.Item {...formItemLayout} label="Icon">
|
||||
{getFieldDecorator('icon', {
|
||||
valuePropName: 'icon',
|
||||
@ -528,6 +558,38 @@ class EditReleaseModal extends React.Component {
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
{/* Package Name field for windows device type and other specific scene using it */}
|
||||
{(formConfig.specificElements.hasOwnProperty('packageName') ||
|
||||
(this.props.type === 'ENTERPRISE' &&
|
||||
this.props.deviceType === 'windows')) && (
|
||||
<Form.Item {...formItemLayout} label="Package Name">
|
||||
{getFieldDecorator('packageName', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the package name',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Package Name" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* Version field for windows device type and other specific scene using it */}
|
||||
{(formConfig.specificElements.hasOwnProperty('version') ||
|
||||
(this.props.type === 'ENTERPRISE' &&
|
||||
this.props.deviceType === 'windows')) && (
|
||||
<Form.Item {...formItemLayout} label="Version">
|
||||
{getFieldDecorator('version', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input the version',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="Version" />)}
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
<Form.Item {...formItemLayout} label="Release Type">
|
||||
{getFieldDecorator('releaseType', {
|
||||
rules: [
|
||||
@ -650,50 +712,59 @@ class EditReleaseModal extends React.Component {
|
||||
})(
|
||||
<div>
|
||||
{metaData.map((data, index) => {
|
||||
return (
|
||||
<InputGroup key={index}>
|
||||
<Row gutter={8}>
|
||||
<Col span={10}>
|
||||
<Input
|
||||
placeholder="key"
|
||||
value={data.key}
|
||||
onChange={e => {
|
||||
metaData[index].key = e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={10}>
|
||||
<Input
|
||||
placeholder="value"
|
||||
value={data.value}
|
||||
onChange={e => {
|
||||
metaData[index].value =
|
||||
e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<Button
|
||||
type="dashed"
|
||||
shape="circle"
|
||||
icon={<MinusOutlined />}
|
||||
onClick={() => {
|
||||
metaData.splice(index, 1);
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</InputGroup>
|
||||
);
|
||||
if (
|
||||
!(
|
||||
data.key ===
|
||||
config.windowsAppxMsiKeyValueForMetaData
|
||||
.metaKeyArray[4]
|
||||
)
|
||||
) {
|
||||
return (
|
||||
<InputGroup key={index}>
|
||||
<Row gutter={8}>
|
||||
<Col span={10}>
|
||||
<Input
|
||||
placeholder="key"
|
||||
value={data.key}
|
||||
onChange={e => {
|
||||
metaData[index].key =
|
||||
e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={10}>
|
||||
<Input
|
||||
placeholder="value"
|
||||
value={data.value}
|
||||
onChange={e => {
|
||||
metaData[index].value =
|
||||
e.currentTarget.value;
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<Button
|
||||
type="dashed"
|
||||
shape="circle"
|
||||
icon={<MinusOutlined />}
|
||||
onClick={() => {
|
||||
metaData.splice(index, 1);
|
||||
this.setState({
|
||||
metaData,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</InputGroup>
|
||||
);
|
||||
}
|
||||
})}
|
||||
<Button
|
||||
type="dashed"
|
||||
|
||||
@ -41,6 +41,8 @@ class ReleaseView extends React.Component {
|
||||
const { app, release } = this.props;
|
||||
const config = this.props.context;
|
||||
const { lifecycle, currentLifecycleStatus } = this.props;
|
||||
let isKeyInclude = false;
|
||||
let metaArrayWithOutWindowsKey = [];
|
||||
if (release == null) {
|
||||
return null;
|
||||
}
|
||||
@ -169,21 +171,31 @@ class ReleaseView extends React.Component {
|
||||
<Text>META DATA</Text>
|
||||
<Row>
|
||||
{metaData.map((data, index) => {
|
||||
return (
|
||||
<Col
|
||||
key={index}
|
||||
lg={8}
|
||||
md={6}
|
||||
xs={24}
|
||||
style={{ marginTop: 15 }}
|
||||
>
|
||||
<Text>{data.key}</Text>
|
||||
<br />
|
||||
<Text type="secondary">{data.value}</Text>
|
||||
</Col>
|
||||
);
|
||||
// Exclude showing the values related to windows app type variables in the metaData UI
|
||||
if (
|
||||
!config.windowsAppxMsiKeyValueForMetaData.metaKeyArray.includes(
|
||||
data.key,
|
||||
)
|
||||
) {
|
||||
isKeyInclude = false;
|
||||
metaArrayWithOutWindowsKey.push(data);
|
||||
return (
|
||||
<Col
|
||||
key={index}
|
||||
lg={8}
|
||||
md={6}
|
||||
xs={24}
|
||||
style={{ marginTop: 15 }}
|
||||
>
|
||||
<Text>{data.key}</Text>
|
||||
<br />
|
||||
<Text type="secondary">{data.value}</Text>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
})}
|
||||
{metaData.length === 0 && (
|
||||
{(metaData.length === 0 ||
|
||||
(!isKeyInclude && metaArrayWithOutWindowsKey.length === 0)) && (
|
||||
<Text type="secondary">No meta data available.</Text>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
@ -40,5 +40,8 @@
|
||||
"color": "#008cc4",
|
||||
"theme": "filled"
|
||||
}
|
||||
},
|
||||
"windowsAppxMsiKeyValueForMetaData": {
|
||||
"metaKeyArray": ["Package_Url", "Dependency_Package_Url", "Certificate_Hash", "Encoded_Cert_Content", "Package_Family_Name", "Product_Id", "Content_Uri", "File_Hash"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,6 +148,8 @@ class ReleaseView extends React.Component {
|
||||
const config = this.props.context;
|
||||
const release = app.applicationReleases[0];
|
||||
|
||||
let isKeyInclude = false;
|
||||
let metaArrayWithOutWindowsKey = [];
|
||||
let metaData = [];
|
||||
try {
|
||||
metaData = JSON.parse(release.metaData);
|
||||
@ -270,24 +272,33 @@ class ReleaseView extends React.Component {
|
||||
</div>
|
||||
<Divider />
|
||||
<Text>META DATA</Text>
|
||||
|
||||
<Row>
|
||||
{metaData.map((data, index) => {
|
||||
return (
|
||||
<Col
|
||||
key={index}
|
||||
lg={8}
|
||||
md={6}
|
||||
xs={24}
|
||||
style={{ marginTop: 15 }}
|
||||
>
|
||||
<Text>{data.key}</Text>
|
||||
<br />
|
||||
<Text type="secondary">{data.value}</Text>
|
||||
</Col>
|
||||
);
|
||||
if (
|
||||
!config.windowsAppxMsiKeyValueForMetaData.metaKeyArray.includes(
|
||||
data.key,
|
||||
)
|
||||
) {
|
||||
isKeyInclude = false;
|
||||
metaArrayWithOutWindowsKey.push(data);
|
||||
return (
|
||||
<Col
|
||||
key={index}
|
||||
lg={8}
|
||||
md={6}
|
||||
xs={24}
|
||||
style={{ marginTop: 15 }}
|
||||
>
|
||||
<Text>{data.key}</Text>
|
||||
<br />
|
||||
<Text type="secondary">{data.value}</Text>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
})}
|
||||
{metaData.length === 0 && (
|
||||
{(metaData.length === 0 ||
|
||||
(!isKeyInclude &&
|
||||
metaArrayWithOutWindowsKey.length === 0)) && (
|
||||
<Text type="secondary">No meta data available.</Text>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
package org.wso2.carbon.device.mgt.common;
|
||||
|
||||
/**
|
||||
* This class holds all the constants used for IOS and Android.
|
||||
* This class holds all the constants used for IOS, Android, Windows.
|
||||
*/
|
||||
public class MDMAppConstants {
|
||||
|
||||
@ -49,6 +49,29 @@ public class MDMAppConstants {
|
||||
public static final String OPCODE_UNINSTALL_APPLICATION = "UNINSTALL_APPLICATION";
|
||||
}
|
||||
|
||||
public class WindowsConstants {
|
||||
|
||||
private WindowsConstants() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
public static final String INSTALL_ENTERPRISE_APPLICATION = "INSTALL_ENTERPRISE_APPLICATION";
|
||||
//App type constants related to window device type
|
||||
public static final String MSI = "MSI";
|
||||
public static final String APPX = "APPX";
|
||||
|
||||
//MSI Meta Key Constant
|
||||
public static final String MSI_PRODUCT_ID = "Product_Id";
|
||||
public static final String MSI_CONTENT_URI = "Content_Uri";
|
||||
public static final String MSI_FILE_HASH = "File_Hash";
|
||||
|
||||
//APPX Meta Key Constant
|
||||
public static final String APPX_PACKAGE_URI = "Package_Url";
|
||||
public static final String APPX_DEPENDENCY_PACKAGE_URL = "Dependency_Package_Url";
|
||||
public static final String APPX_CERTIFICATE_HASH = "Certificate_Hash";
|
||||
public static final String APPX_ENCODED_CERT_CONTENT = "Encoded_Cert_Content";
|
||||
public static final String APPX_PACKAGE_FAMILY_NAME = "Package_Family_Name";
|
||||
}
|
||||
|
||||
public class RegistryConstants {
|
||||
|
||||
private RegistryConstants() {
|
||||
|
||||
@ -62,6 +62,10 @@ public class App {
|
||||
private String location;
|
||||
@ApiModelProperty(name = "properties", value = "List of meta data.", required = true)
|
||||
private Properties properties;
|
||||
@ApiModelProperty(name = "metaData",
|
||||
value = "Meta data of the application release",
|
||||
required = true)
|
||||
private String metaData;
|
||||
|
||||
public MobileAppTypes getType() {
|
||||
return type;
|
||||
@ -142,4 +146,8 @@ public class App {
|
||||
public void setProperties(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public String getMetaData() { return metaData; }
|
||||
|
||||
public void setMetaData(String metaData) { this.metaData = metaData; }
|
||||
}
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.common.app.mgt.windows;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* This class represents the Windows Enterprise App Types information.
|
||||
*/
|
||||
public class EnterpriseApplication implements Serializable {
|
||||
|
||||
private HostedAppxApplication hostedAppxApplication;
|
||||
private HostedMSIApplication hostedMSIApplication;
|
||||
|
||||
public HostedAppxApplication getHostedAppxApplication() {
|
||||
return hostedAppxApplication;
|
||||
}
|
||||
|
||||
public void setHostedAppxApplication(HostedAppxApplication hostedAppxApplication) {
|
||||
this.hostedAppxApplication = hostedAppxApplication;
|
||||
}
|
||||
|
||||
public HostedMSIApplication getHostedMSIApplication() {
|
||||
return hostedMSIApplication;
|
||||
}
|
||||
|
||||
public void setHostedMSIApplication(HostedMSIApplication hostedMSIApplication) {
|
||||
this.hostedMSIApplication = hostedMSIApplication;
|
||||
}
|
||||
|
||||
public String toJSON() {
|
||||
Gson gson = new Gson();
|
||||
return gson.toJson(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.common.app.mgt.windows;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HostedAppxApplication {
|
||||
|
||||
private String packageUri;
|
||||
private String packageFamilyName;
|
||||
private List<String> dependencyPackageUri;
|
||||
private String certificateHash;
|
||||
private String encodedCertificate;
|
||||
|
||||
public String getPackageUri() {
|
||||
return packageUri;
|
||||
}
|
||||
|
||||
public void setPackageUri(String packageUri) {
|
||||
this.packageUri = packageUri;
|
||||
}
|
||||
|
||||
public String getPackageFamilyName() {
|
||||
return packageFamilyName;
|
||||
}
|
||||
|
||||
public void setPackageFamilyName(String packageFamilyName) {
|
||||
this.packageFamilyName = packageFamilyName;
|
||||
}
|
||||
|
||||
public List<String> getDependencyPackageUri() {
|
||||
return dependencyPackageUri;
|
||||
}
|
||||
|
||||
public void setDependencyPackageUri(List<String> dependencyPackageUri) {
|
||||
this.dependencyPackageUri = dependencyPackageUri;
|
||||
}
|
||||
|
||||
public String getCertificateHash() {
|
||||
return certificateHash;
|
||||
}
|
||||
|
||||
public void setCertificateHash(String certificateHash) {
|
||||
this.certificateHash = certificateHash;
|
||||
}
|
||||
|
||||
public String getEncodedCertificate() {
|
||||
return encodedCertificate;
|
||||
}
|
||||
|
||||
public void setEncodedCertificate(String encodedCertificate) {
|
||||
this.encodedCertificate = encodedCertificate;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.common.app.mgt.windows;
|
||||
|
||||
|
||||
public class HostedMSIApplication {
|
||||
|
||||
private String productId;
|
||||
private String contentUrl;
|
||||
private String fileHash;
|
||||
|
||||
public String getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(String productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
public String getContentUrl() {
|
||||
return contentUrl;
|
||||
}
|
||||
|
||||
public void setContentUrl(String contentUrl) {
|
||||
this.contentUrl = contentUrl;
|
||||
}
|
||||
|
||||
public String getFileHash() {
|
||||
return fileHash;
|
||||
}
|
||||
|
||||
public void setFileHash(String fileHash) {
|
||||
this.fileHash = fileHash;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.core.util;
|
||||
|
||||
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.device.mgt.common.MDMAppConstants;
|
||||
import org.wso2.carbon.device.mgt.common.app.mgt.App;
|
||||
import org.wso2.carbon.device.mgt.common.app.mgt.windows.EnterpriseApplication;
|
||||
import org.wso2.carbon.device.mgt.common.app.mgt.windows.HostedAppxApplication;
|
||||
import org.wso2.carbon.device.mgt.common.app.mgt.windows.HostedMSIApplication;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.UnknownApplicationTypeException;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
||||
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class contains the all the operations related to Windows.
|
||||
*/
|
||||
public class MDMWindowsOperationUtil {
|
||||
|
||||
private static final Log log = LogFactory.getLog(MDMWindowsOperationUtil.class);
|
||||
|
||||
/**
|
||||
* This method is used to create Install Authentication operation.
|
||||
*
|
||||
* @param application MobileApp application
|
||||
* @return operation object
|
||||
* @throws UnknownApplicationTypeException
|
||||
*/
|
||||
public static Operation createInstallAppOperation(App application) throws UnknownApplicationTypeException {
|
||||
|
||||
ProfileOperation operation = new ProfileOperation();
|
||||
operation.setCode(MDMAppConstants.WindowsConstants.INSTALL_ENTERPRISE_APPLICATION);
|
||||
operation.setType(Operation.Type.PROFILE);
|
||||
String appType = windowsAppType(application.getName());
|
||||
String metaData = application.getMetaData();
|
||||
JsonArray metaJsonArray = jsonStringToArray(metaData);
|
||||
|
||||
switch (application.getType()) {
|
||||
case ENTERPRISE:
|
||||
EnterpriseApplication enterpriseApplication = new EnterpriseApplication();
|
||||
if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.APPX)) {
|
||||
HostedAppxApplication hostedAppxApplication = new HostedAppxApplication();
|
||||
List<String> dependencyPackageList = new ArrayList<>();
|
||||
for (int i = 0; i < metaJsonArray.size(); i++) {
|
||||
JsonElement metaElement = metaJsonArray.get(i);
|
||||
JsonObject metaObject = metaElement.getAsJsonObject();
|
||||
|
||||
if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_URI.equals(metaObject.get("key").getAsString())) {
|
||||
hostedAppxApplication.setPackageUri(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
else if (MDMAppConstants.WindowsConstants.APPX_PACKAGE_FAMILY_NAME.equals(metaObject.get("key").getAsString())) {
|
||||
hostedAppxApplication.setPackageFamilyName(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
else if (MDMAppConstants.WindowsConstants.APPX_DEPENDENCY_PACKAGE_URL.equals(metaObject.get("key").getAsString())
|
||||
&& metaObject.has("value")) {
|
||||
dependencyPackageList.add(metaObject.get("value").getAsString().trim());
|
||||
hostedAppxApplication.setDependencyPackageUri(dependencyPackageList);
|
||||
}
|
||||
else if (MDMAppConstants.WindowsConstants.APPX_CERTIFICATE_HASH.equals(metaObject.get("key").getAsString())
|
||||
&& metaObject.has("value")) {
|
||||
hostedAppxApplication.setCertificateHash(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
else if (MDMAppConstants.WindowsConstants.APPX_ENCODED_CERT_CONTENT.equals(metaObject.get("key").getAsString())
|
||||
&& metaObject.has("value")) {
|
||||
hostedAppxApplication.setEncodedCertificate(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
}
|
||||
enterpriseApplication.setHostedAppxApplication(hostedAppxApplication);
|
||||
|
||||
} else if (appType.equalsIgnoreCase(MDMAppConstants.WindowsConstants.MSI)) {
|
||||
HostedMSIApplication hostedMSIApplication = new HostedMSIApplication();
|
||||
for (int i = 0; i < metaJsonArray.size(); i++) {
|
||||
JsonElement metaElement = metaJsonArray.get(i);
|
||||
JsonObject metaObject = metaElement.getAsJsonObject();
|
||||
if (MDMAppConstants.WindowsConstants.MSI_PRODUCT_ID.equals(metaObject.get("key").getAsString())) {
|
||||
hostedMSIApplication.setProductId(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
else if (MDMAppConstants.WindowsConstants.MSI_CONTENT_URI.equals(metaObject.get("key").getAsString())) {
|
||||
hostedMSIApplication.setContentUrl(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
else if (MDMAppConstants.WindowsConstants.MSI_FILE_HASH.equals(metaObject.get("key").getAsString())) {
|
||||
hostedMSIApplication.setFileHash(metaObject.get("value").getAsString().trim());
|
||||
}
|
||||
}
|
||||
enterpriseApplication.setHostedMSIApplication(hostedMSIApplication);
|
||||
}
|
||||
operation.setPayLoad(enterpriseApplication.toJSON());
|
||||
break;
|
||||
default:
|
||||
String msg = "Application type " + application.getType() + " is not supported";
|
||||
log.error(msg);
|
||||
throw new UnknownApplicationTypeException(msg);
|
||||
}
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the installer file extension type for windows type apps(either appx or msi)
|
||||
*
|
||||
* @param installerName of the app type
|
||||
* @return string extension of the windows app types(either appx or msi)
|
||||
*/
|
||||
public static String windowsAppType(String installerName) {
|
||||
String extension = installerName.substring(installerName.lastIndexOf(".") + 1);
|
||||
return extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to convert Json String to Json Array
|
||||
*
|
||||
* @param metaData metaData string array object containing the windows app type specific parameters
|
||||
* @return the metaData Json String as Json Array
|
||||
*/
|
||||
public static JsonArray jsonStringToArray(String metaData) {
|
||||
JsonArray metaJsonArray = new JsonParser().parse(metaData).getAsJsonArray();
|
||||
return metaJsonArray;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user