Skip to content

Commit

Permalink
v5.28.1: Admin can limit downloading updates by network. Added an opt…
Browse files Browse the repository at this point in the history
…ion to encrypt the mobile device storage.
  • Loading branch information
vmayorow committed Oct 9, 2024
1 parent 96f6d7b commit b1151c2
Show file tree
Hide file tree
Showing 25 changed files with 246 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public List<Application> getConfigurationApplications(Integer id) {
return getLinkedList(
id,
this.mapper::getConfigurationById,
customerId -> this.mapper.getConfigurationApplications(customerId, id),
customerId -> this.mapper.getConfigurationApplications(customerId, id, "ca" + CryptoUtil.randomHexString(8)),
SecurityException::onConfigurationAccessViolation
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public class Configuration implements CustomerData, Serializable {
private String appUpdateFrom;
@ApiModelProperty(value = "An end time for system update period formatted as HH:MM.")
private String appUpdateTo;
@ApiModelProperty("Limits downloading updates")
private DownloadUpdatesType downloadUpdates = DownloadUpdatesType.UNLIMITED;

@ApiModelProperty("A flag indicating if GPS is enabled on device")
private Boolean gps;
Expand Down Expand Up @@ -146,6 +148,8 @@ public class Configuration implements CustomerData, Serializable {
private String wifiPassword;
@ApiModelProperty("WiFi security type for provisioning: NONE/WPA/WEP/EAP")
private String wifiSecurityType;
@ApiModelProperty("Device encryption")
private boolean encryptDevice;
@ApiModelProperty("Additional QR code parameters")
private String qrParameters;
@ApiModelProperty("Prefer mobile data for provisioning")
Expand Down Expand Up @@ -434,6 +438,14 @@ public void setWifiSecurityType(String wifiSecurityType) {
this.wifiSecurityType = wifiSecurityType;
}

public boolean isEncryptDevice() {
return encryptDevice;
}

public void setEncryptDevice(boolean encryptDevice) {
this.encryptDevice = encryptDevice;
}

public String getQrParameters() {
return qrParameters;
}
Expand Down Expand Up @@ -578,6 +590,14 @@ public void setAppUpdateTo(String appUpdateTo) {
this.appUpdateTo = appUpdateTo;
}

public DownloadUpdatesType getDownloadUpdates() {
return downloadUpdates;
}

public void setDownloadUpdates(DownloadUpdatesType downloadUpdates) {
this.downloadUpdates = downloadUpdates;
}

public List<ApplicationSetting> getApplicationSettings() {
return applicationSettings;
}
Expand Down Expand Up @@ -838,6 +858,7 @@ public Configuration newCopy() {
copy.setScheduleAppUpdate(isScheduleAppUpdate());
copy.setAppUpdateFrom(getAppUpdateFrom());
copy.setAppUpdateTo(getAppUpdateTo());
copy.setDownloadUpdates(getDownloadUpdates());

copy.setMainAppId(getMainAppId());
copy.setContentAppId(getContentAppId());
Expand All @@ -846,6 +867,7 @@ public Configuration newCopy() {
copy.setWifiSSID(getWifiSSID());
copy.setWifiPassword(getWifiPassword());
copy.setWifiSecurityType(getWifiSecurityType());
copy.setEncryptDevice(isEncryptDevice());
copy.setQrParameters(getQrParameters());
copy.setKioskHome(getKioskHome());
copy.setKioskRecents(getKioskRecents());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
*
* Headwind MDM: Open Source Android MDM Software
* https://h-mdm.com
*
* Copyright (C) 2019 Headwind Solutions LLC (http://h-sms.com)
*
* Licensed 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 com.hmdm.persistence.domain;

/**
* <p>An enumeration over the supported download update types.</p>
*
* @author isv
*/
public enum DownloadUpdatesType {
UNLIMITED(null),
LIMITED("limited"),
WIFI("wifi");

/**
* <p>A string value transmitted between the server and the device to represent this item.</p>
*/
private String transmittedValue;

private DownloadUpdatesType(String transmittedValue) {
this.transmittedValue = transmittedValue;
}

/**
* <p>Gets the textual presentation of this type for transmission to device.</p>
*
* @return a string value transmitted between the server and the device to represent this item.
*/
public String getTransmittedValue() {
return transmittedValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ List<Configuration> getAllConfigurationsByValue(@Param("customerId") int custome
"wifiSSID=#{wifiSSID}, " +
"wifiPassword=#{wifiPassword}, " +
"wifiSecurityType=#{wifiSecurityType}, " +
"encryptDevice=#{encryptDevice}, " +
"qrParameters=#{qrParameters}, " +
"mobileEnrollment=#{mobileEnrollment}, " +
"kioskHome=#{kioskHome}, " +
Expand All @@ -124,6 +125,7 @@ List<Configuration> getAllConfigurationsByValue(@Param("customerId") int custome
"scheduleAppUpdate=#{scheduleAppUpdate}, " +
"appUpdateFrom=#{appUpdateFrom}, " +
"appUpdateTo=#{appUpdateTo}, " +
"downloadUpdates=#{downloadUpdates}, " +
"defaultFilePath=#{defaultFilePath} " +
"WHERE id=#{id}"})
void updateConfiguration(Configuration configuration);
Expand Down Expand Up @@ -160,7 +162,8 @@ void saveConfigurationApplicationUsageParameters(
* @param id an ID of a configuration.
* @return a list of all existing applications with set parameters of usage by specified configuration.
*/
List<Application> getConfigurationApplications(@Param("customerId") Integer customerId, @Param("id") Integer id);
List<Application> getConfigurationApplications(@Param("customerId") Integer customerId, @Param("id") Integer id,
@Param("tempTable") String tempTable);

/**
* <p>Gets the list of applications used by specified configuration.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@
lockVolume, manageVolume, volume, passwordMode, orientation,
runDefaultLauncher, disableScreenshots, autostartForeground, timeZone, allowedClasses, newServerUrl,
lockSafeSettings, permissive, kioskExit, showWifi, mainAppId, eventReceivingComponent, kioskMode,
contentAppId, wifiSSID, wifiPassword, wifiSecurityType, qrParameters, mobileEnrollment, kioskHome, kioskRecents,
contentAppId, wifiSSID, wifiPassword, wifiSecurityType, encryptDevice, qrParameters, mobileEnrollment, kioskHome, kioskRecents,
kioskNotifications, kioskSystemInfo, kioskKeyguard, kioskLockButtons, restrictions, autoUpdate,
blockStatusBar, systemUpdateType, systemUpdateFrom, systemUpdateTo,
scheduleAppUpdate, appUpdateFrom, appUpdateTo, defaultFilePath)
scheduleAppUpdate, appUpdateFrom, appUpdateTo, downloadUpdates, defaultFilePath)
VALUES (#{name}, #{description}, #{type}, #{password}, #{backgroundColor}, #{textColor}, #{backgroundImageUrl},
#{iconSize}, #{desktopHeader}, #{desktopHeaderTemplate}, #{displayStatus}, #{useDefaultDesignSettings}, #{customerId},
#{gps}, #{bluetooth}, #{wifi}, #{mobileData}, #{usbStorage}, #{requestUpdates}, #{disableLocation}, #{appPermissions},
#{pushOptions}, #{keepaliveTime}, #{autoBrightness}, #{brightness}, #{manageTimeout}, #{timeout},
#{lockVolume}, #{manageVolume}, #{volume}, #{passwordMode}, #{orientation},
#{runDefaultLauncher}, #{disableScreenshots}, #{autostartForeground}, #{timeZone}, #{allowedClasses}, #{newServerUrl},
#{lockSafeSettings}, #{permissive}, #{kioskExit}, #{showWifi}, #{mainAppId}, #{eventReceivingComponent}, #{kioskMode},
#{contentAppId}, #{wifiSSID}, #{wifiPassword}, #{wifiSecurityType}, #{qrParameters}, #{mobileEnrollment}, #{kioskHome}, #{kioskRecents},
#{contentAppId}, #{wifiSSID}, #{wifiPassword}, #{wifiSecurityType}, #{encryptDevice}, #{qrParameters}, #{mobileEnrollment}, #{kioskHome}, #{kioskRecents},
#{kioskNotifications}, #{kioskSystemInfo}, #{kioskKeyguard}, #{kioskLockButtons}, #{restrictions}, #{autoUpdate},
#{blockStatusBar}, #{systemUpdateType}, #{systemUpdateFrom}, #{systemUpdateTo},
#{scheduleAppUpdate}, #{appUpdateFrom}, #{appUpdateTo}, #{defaultFilePath})
#{scheduleAppUpdate}, #{appUpdateFrom}, #{appUpdateTo}, #{downloadUpdates}, #{defaultFilePath})
</insert>

<insert id="insertConfigurationApplications">
Expand Down Expand Up @@ -90,6 +90,7 @@
</insert>

<select id="getConfigurationApplications" resultType="Application">
CREATE TEMP TABLE ${tempTable} ON COMMIT DROP AS SELECT * FROM configurationApplications WHERE configurationApplications.configurationId = #{id};
SELECT applications.id, applications.name, applications.pkg, applications.runAfterInstall, applications.runAtBoot,
applications.type, applications.iconText, applications.iconId,
applicationVersions.version, applicationVersions.url,
Expand Down Expand Up @@ -117,7 +118,7 @@
INNER JOIN applicationVersions AS latestAppVersion ON latestAppVersion.applicationId = applications.id AND latestAppVersion.id=applications.latestversion
INNER JOIN customers ON customers.id = applications.customerId
INNER JOIN applicationVersions ON applicationVersions.applicationId = applications.id
LEFT JOIN configurationApplications ON applicationVersions.id = configurationApplications.applicationVersionId AND configurationApplications.configurationId = #{id}
LEFT JOIN ${tempTable} configurationApplications ON applicationVersions.id = configurationApplications.applicationVersionId AND configurationApplications.configurationId = #{id}
LEFT JOIN configurationApplicationParameters cap ON applications.id = cap.applicationId AND cap.configurationId = #{id}
WHERE (applications.customerId=#{customerId}
OR customers.master
Expand Down
2 changes: 2 additions & 0 deletions common/src/main/java/com/hmdm/rest/json/SyncResponseInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ public interface SyncResponseInt {

String getAppUpdateTo();

String getDownloadUpdates();

List<SyncApplicationSettingInt> getApplicationSettings();

Boolean getUsbStorage();
Expand Down
4 changes: 4 additions & 0 deletions plugins/push/src/main/webapp/push.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ angular.module('plugin-push', ['ngResource', 'ui.bootstrap', 'ui.router', 'ngTag
deleteDir: "{path: \"/path/to/dir\"}",
purgeDir: "{path: \"/path/to/dir\", recursive: \"1\"}",
permissiveMode: "",
runCommand: "{command: \"shell command\"}",
reboot: "",
exitKiosk: "",
clearDownloadHistory: "",
"(custom)": ""
};

Expand Down
4 changes: 4 additions & 0 deletions plugins/push/src/main/webapp/views/push.modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
<option>deleteDir</option>
<option>purgeDir</option>
<option>permissiveMode</option>
<option>runCommand</option>
<option>reboot</option>
<option>exitKiosk</option>
<option>clearDownloadHistory</option>
<option>(custom)</option>
</select>
</div>
Expand Down
13 changes: 13 additions & 0 deletions server/src/main/java/com/hmdm/rest/json/SyncResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ public class SyncResponse implements Serializable, SyncResponseInt {
@JsonInclude(JsonInclude.Include.NON_NULL)
private String appUpdateTo;

@ApiModelProperty("Limitations of downloading updates")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String downloadUpdates;

@ApiModelProperty(value = "A list of application settings to apply on device")
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<SyncApplicationSettingInt> applicationSettings;
Expand Down Expand Up @@ -565,6 +569,15 @@ public void setAppUpdateTo(String appUpdateTo) {
this.appUpdateTo = appUpdateTo;
}

@Override
public String getDownloadUpdates() {
return downloadUpdates;
}

public void setDownloadUpdates(String downloadUpdates) {
this.downloadUpdates = downloadUpdates;
}

@Override
public List<SyncApplicationSettingInt> getApplicationSettings() {
return applicationSettings;
Expand Down
13 changes: 8 additions & 5 deletions server/src/main/java/com/hmdm/rest/resource/QRCodeResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,20 @@ public javax.ws.rs.core.Response generateQRCode(@PathParam("id") @ApiParam("Conf
}
}

String s = "{\n" +
StringBuffer sb = new StringBuffer("{\n" +
"\"android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME\":\"" + appMain.getPkg() +"/" + configuration.getEventReceivingComponent() + "\",\n" +
"\"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION\":\"" + apkUrl + "\",\n" +
"\"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM\":\"" + sha256 + "\",\n" +
wifiSsidEntry + wifiPasswordEntry + mobileEnrollmentEntry +
"\"android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED\":true,\n" +
"\"android.app.extra.PROVISIONING_SKIP_ENCRYPTION\":true,\n" +
miscQrParametersEntry +
"\"android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED\":true,\n");
if (!configuration.isEncryptDevice()) {
sb.append("\"android.app.extra.PROVISIONING_SKIP_ENCRYPTION\":true,\n");
}
sb.append(miscQrParametersEntry +
"\"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE\": " +
generateExtrasBundle(deviceID, createOnDemand, configuration, groups, useId, req.getContextPath()) +
"}\n";
"}\n");
final String s = sb.toString();

logger.info("The base for QR code generation:\n{}", s);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ private Response getDeviceSettingInternal(Device dbDevice, boolean migration, bo
data.setAppUpdateFrom(configuration.getAppUpdateFrom());
data.setAppUpdateTo(configuration.getAppUpdateTo());
}
data.setDownloadUpdates(configuration.getDownloadUpdates().getTransmittedValue());
data.setPasswordMode(configuration.getPasswordMode());
data.setOrientation(configuration.getOrientation());
data.setDisplayStatus(configuration.isDisplayStatus() ? true : null);
Expand Down
3 changes: 2 additions & 1 deletion server/src/main/java/com/hmdm/task/CustomerStatusTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ public void run() {
c.getInactiveState() + "/P" + c.getPauseState() + "/A" + c.getAbandonState() + "<br>\n";
}
if (!adminEmail.equals("")) {
emailService.sendEmail(adminEmail, adminSubj, adminBody);
// This info is not required now
// emailService.sendEmail(adminEmail, adminSubj, adminBody);
}

// Notify Mailchimp
Expand Down
20 changes: 20 additions & 0 deletions server/src/main/resources/liquibase/db.changelog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2506,4 +2506,24 @@
</rollback>
</changeSet>

<changeSet id="21.09.24-14:21" author="seva" context="common">
<comment>Add MDM device encryption column to configurations</comment>
<sql>
ALTER TABLE configurations ADD COLUMN encryptDevice BOOLEAN NOT NULL DEFAULT false;
</sql>
<rollback>
ALTER TABLE configurations DROP COLUMN encryptDevice;
</rollback>
</changeSet>

<changeSet id="25.09.24-11:49" author="seva" context="common">
<comment>Column,new: configurations#downloadUpdates</comment>
<sql>
ALTER TABLE configurations ADD COLUMN downloadUpdates VARCHAR(20) NOT NULL DEFAULT 'UNLIMITED';
</sql>
<rollback>
ALTER TABLE configurations DROP COLUMN downloadUpdates;
</rollback>
</changeSet>

</databaseChangeLog>
2 changes: 1 addition & 1 deletion server/src/main/webapp/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ angular.module('headwind-kiosk',
'ja_JP': 'ja_JP'
})
.constant("LOCALIZATION_BUNDLES", ['en_US', 'ru_RU', 'fr_FR', 'pt_PT', 'ar_AE', 'es_ES', 'de_DE', 'zh_TW', 'zh_CN', 'ja_JP'])
.constant("APP_VERSION", "5.27.2") // Update this value on each commit
.constant("APP_VERSION", "5.28.1") // Update this value on each commit
.constant("ENGLISH", "en_US")
.provider('getBrowserLanguage', function (ENGLISH, SUPPORTED_LANGUAGES) {
this.f = function () {
Expand Down
27 changes: 25 additions & 2 deletions server/src/main/webapp/app/components/main/view/configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h3 ng-if="isTypical"><span localized>form.configuration.title.typical</span> &q
</div>
</div>

<div class='row'>
<!-- Commented as a deprecated option <div class='row'>
<label class='col-sm-3 control-label' localized>form.configuration.settings.block.status.bar</label>
<div class='col-sm-1'>
<input ng-model='configuration.blockStatusBar' name="mdm32323" type='checkbox' class='form-control common-checkbox'/>
Expand All @@ -69,7 +69,7 @@ <h3 ng-if="isTypical"><span localized>form.configuration.title.typical</span> &q
<div class='form-group'>
<div class='col-sm-3'>&nbsp;</div>
<div class='col-sm-9 field-hint' localized>form.configuration.settings.block.status.bar.hint</div>
</div>
</div> -->

<div class='form-group'>
<label class='col-sm-3 control-label' for="requestUpdates-c"
Expand Down Expand Up @@ -343,6 +343,22 @@ <h3 ng-if="isTypical"><span localized>form.configuration.title.typical</span> &q
</div>
</div>

<div class='form-group'>
<label class='col-sm-3 control-label' for="passwordMode-c"
localized>form.configuration.settings.download.updates</label>
<div class='col-sm-9'>
<select class='form-control' id="downloadUpdates-c" name="downloadUpdates"
ng-model='configuration.downloadUpdates'>
<option ng-value="'UNLIMITED'" ng-selected="configuration.downloadUpdates === 'UNLIMITED'"
localized>form.configuration.settings.download.updates.unlimited</option>
<option ng-value="'LIMITED'" ng-selected="configuration.downloadUpdates === 'LIMITED'"
localized>form.configuration.settings.download.updates.limited</option>
<option ng-value="'WIFI'" ng-selected="configuration.downloadUpdates === 'WIFI'"
localized>form.configuration.settings.download.updates.wifi</option>
</select>
</div>
</div>

<div class='form-group'>
<label class='col-sm-3 control-label' for="passwordMode-c"
localized>form.configuration.settings.password.mode</label>
Expand Down Expand Up @@ -848,6 +864,13 @@ <h3 ng-if="isTypical"><span localized>form.configuration.title.typical</span> &q
</div>
</div>

<div class='form-group'>
<label class='col-sm-3 control-label' localized>form.configuration.settings.mdm.encrypt.device</label>
<div class='col-sm-1'>
<input ng-model='configuration.encryptDevice' name="encryptDevice-c" type='checkbox' class='form-control'/>
</div>
</div>

<div ng-if="!configuration.kioskMode">

<div class='form-group'>
Expand Down
Loading

0 comments on commit b1151c2

Please sign in to comment.