From 0e601995ec8872fec66b5b6700fe24f2c542da21 Mon Sep 17 00:00:00 2001 From: Jonas L Date: Mon, 25 Mar 2019 00:00:00 +0000 Subject: [PATCH] Add suport for accessibility service permission --- src/action/ignoremanipulation.ts | 10 +++- src/action/updatedevicestatus.ts | 10 +++- src/api/validator.ts | 6 +++ src/database/device.ts | 26 +++++++++-- .../migrations/20190402-add-as-permission.ts | 46 +++++++++++++++++++ src/function/device/prepare-device-entry.ts | 4 +- .../updatedevicestatus.ts | 14 ++++++ .../ignoremanipulation.ts | 4 ++ src/function/sync/get-server-data-status.ts | 4 +- src/object/serverdatastatus.ts | 2 + 10 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 src/database/migration/migrations/20190402-add-as-permission.ts diff --git a/src/action/ignoremanipulation.ts b/src/action/ignoremanipulation.ts index 12bd44e..7b10259 100644 --- a/src/action/ignoremanipulation.ts +++ b/src/action/ignoremanipulation.ts @@ -26,13 +26,14 @@ export class IgnoreManipulationAction extends ParentAction { readonly ignoreNotificationAccessManipulation: boolean readonly ignoreUsageStatsAccessManipulation: boolean readonly ignoreOverlayPermissionManipulation: boolean + readonly ignoreAccessibilityServiceManipulation: boolean readonly ignoreDidReboot: boolean readonly ignoreHadManipulation: boolean constructor ({ deviceId, ignoreDeviceAdminManipulation, ignoreDeviceAdminManipulationAttempt, ignoreAppDowngrade, ignoreNotificationAccessManipulation, ignoreUsageStatsAccessManipulation, - ignoreOverlayPermissionManipulation, ignoreDidReboot, ignoreHadManipulation + ignoreOverlayPermissionManipulation, ignoreAccessibilityServiceManipulation, ignoreDidReboot, ignoreHadManipulation }: { deviceId: string ignoreDeviceAdminManipulation: boolean @@ -41,6 +42,7 @@ export class IgnoreManipulationAction extends ParentAction { ignoreNotificationAccessManipulation: boolean ignoreUsageStatsAccessManipulation: boolean ignoreOverlayPermissionManipulation: boolean + ignoreAccessibilityServiceManipulation: boolean ignoreDidReboot: boolean ignoreHadManipulation: boolean }) { @@ -55,6 +57,7 @@ export class IgnoreManipulationAction extends ParentAction { this.ignoreNotificationAccessManipulation = ignoreNotificationAccessManipulation this.ignoreUsageStatsAccessManipulation = ignoreUsageStatsAccessManipulation this.ignoreOverlayPermissionManipulation = ignoreOverlayPermissionManipulation + this.ignoreAccessibilityServiceManipulation = ignoreAccessibilityServiceManipulation this.ignoreDidReboot = ignoreDidReboot this.ignoreHadManipulation = ignoreHadManipulation } @@ -67,11 +70,12 @@ export class IgnoreManipulationAction extends ParentAction { downgrade: this.ignoreAppDowngrade, notification: this.ignoreNotificationAccessManipulation, overlay: this.ignoreOverlayPermissionManipulation, + accessibilityService: this.ignoreAccessibilityServiceManipulation, usageStats: this.ignoreUsageStatsAccessManipulation, hadManipulation: this.ignoreHadManipulation }) - static parse = ({ deviceId, admin, adminA, downgrade, notification, usageStats, overlay, reboot, hadManipulation }: SerializedIgnoreManipulationAction) => ( + static parse = ({ deviceId, admin, adminA, downgrade, notification, usageStats, overlay, accessibilityService, reboot, hadManipulation }: SerializedIgnoreManipulationAction) => ( new IgnoreManipulationAction({ deviceId, ignoreDeviceAdminManipulation: admin, @@ -80,6 +84,7 @@ export class IgnoreManipulationAction extends ParentAction { ignoreUsageStatsAccessManipulation: usageStats, ignoreNotificationAccessManipulation: notification, ignoreOverlayPermissionManipulation: !!overlay, + ignoreAccessibilityServiceManipulation: !!accessibilityService, ignoreDidReboot: !!reboot, ignoreHadManipulation: hadManipulation }) @@ -98,4 +103,5 @@ export interface SerializedIgnoreManipulationAction { // was added at a later version reboot?: boolean overlay?: boolean + accessibilityService?: boolean } diff --git a/src/action/updatedevicestatus.ts b/src/action/updatedevicestatus.ts index ba4d2b9..41c56f7 100644 --- a/src/action/updatedevicestatus.ts +++ b/src/action/updatedevicestatus.ts @@ -25,14 +25,16 @@ export class UpdateDeviceStatusAction extends AppLogicAction { readonly newUsageStatsPermissionStatus?: RuntimePermissionStatus readonly newNotificationAccessPermission?: NewPermissionStatus readonly newOverlayPermission?: RuntimePermissionStatus + readonly newAccessibilityServiceEnabled?: boolean readonly newAppVersion?: number readonly didReboot: boolean - constructor ({ newProtetionLevel, newUsageStatsPermissionStatus, newNotificationAccessPermission, newOverlayPermission, newAppVersion, didReboot }: { + constructor ({ newProtetionLevel, newUsageStatsPermissionStatus, newNotificationAccessPermission, newOverlayPermission, newAccessibilityServiceEnabled, newAppVersion, didReboot }: { newProtetionLevel?: ProtectionLevel newUsageStatsPermissionStatus?: RuntimePermissionStatus newNotificationAccessPermission?: NewPermissionStatus newOverlayPermission?: RuntimePermissionStatus + newAccessibilityServiceEnabled?: boolean newAppVersion?: number didReboot: boolean }) { @@ -48,6 +50,7 @@ export class UpdateDeviceStatusAction extends AppLogicAction { this.newUsageStatsPermissionStatus = newUsageStatsPermissionStatus this.newNotificationAccessPermission = newNotificationAccessPermission this.newOverlayPermission = newOverlayPermission + this.newAccessibilityServiceEnabled = newAccessibilityServiceEnabled this.newAppVersion = newAppVersion this.didReboot = didReboot } @@ -58,16 +61,18 @@ export class UpdateDeviceStatusAction extends AppLogicAction { usageStats: this.newUsageStatsPermissionStatus, notificationAccess: this.newNotificationAccessPermission, overlayPermission: this.newOverlayPermission, + accessibilityServiceEnabled: this.newAccessibilityServiceEnabled, appVersion: this.newAppVersion, didReboot: this.didReboot }) - static parse = ({ protectionLevel, usageStats, notificationAccess, overlayPermission, appVersion, didReboot }: SerializedUpdateDeviceStatusAction) => ( + static parse = ({ protectionLevel, usageStats, notificationAccess, overlayPermission, accessibilityServiceEnabled, appVersion, didReboot }: SerializedUpdateDeviceStatusAction) => ( new UpdateDeviceStatusAction({ newProtetionLevel: protectionLevel, newUsageStatsPermissionStatus: usageStats, newNotificationAccessPermission: notificationAccess, newOverlayPermission: overlayPermission, + newAccessibilityServiceEnabled: accessibilityServiceEnabled, newAppVersion: appVersion, didReboot: !!didReboot }) @@ -80,6 +85,7 @@ export interface SerializedUpdateDeviceStatusAction { usageStats?: RuntimePermissionStatus notificationAccess?: NewPermissionStatus overlayPermission?: RuntimePermissionStatus + accessibilityServiceEnabled?: boolean appVersion?: number didReboot?: boolean } diff --git a/src/api/validator.ts b/src/api/validator.ts index 909c97d..351da7d 100644 --- a/src/api/validator.ts +++ b/src/api/validator.ts @@ -336,6 +336,9 @@ const definitions = { }, "overlay": { "type": "boolean" + }, + "accessibilityService": { + "type": "boolean" } }, "additionalProperties": false, @@ -1123,6 +1126,9 @@ const definitions = { ], "type": "string" }, + "accessibilityServiceEnabled": { + "type": "boolean" + }, "appVersion": { "type": "number" }, diff --git a/src/database/device.ts b/src/database/device.ts index 80e6021..c1e7e99 100644 --- a/src/database/device.ts +++ b/src/database/device.ts @@ -74,9 +74,15 @@ export interface DeviceAttributesVersion7 { highestOverlayPermission: RuntimePermissionStatus } +export interface DeviceAttributesVersion8 { + // as = accessibility service + asEnabled: boolean + wasAsEnabled: boolean +} + export type DeviceAttributes = DeviceAttributesVersion1 & DeviceAttributesVersion2 & DeviceAttributesVersion3 & DeviceAttributesVersion4 & DeviceAttributesVersion5 & - DeviceAttributesVersion6 & DeviceAttributesVersion7 + DeviceAttributesVersion6 & DeviceAttributesVersion7 & DeviceAttributesVersion8 export type DeviceInstance = Sequelize.Instance & DeviceAttributes export type DeviceModel = Sequelize.Model @@ -191,6 +197,17 @@ export const attributesVersion7: SequelizeAttributes = } } +export const attributesVersion8: SequelizeAttributes = { + asEnabled: { + ...booleanColumn, + defaultValue: false + }, + wasAsEnabled: { + ...booleanColumn, + defaultValue: false + } +} + export const attributes: SequelizeAttributes = { ...attributesVersion1, ...attributesVersion2, @@ -198,7 +215,8 @@ export const attributes: SequelizeAttributes = { ...attributesVersion4, ...attributesVersion5, ...attributesVersion6, - ...attributesVersion7 + ...attributesVersion7, + ...attributesVersion8 } export const createDeviceModel = (sequelize: Sequelize.Sequelize): DeviceModel => sequelize.define('Device', attributes) @@ -208,6 +226,7 @@ export const hasDeviceManipulation = (device: DeviceAttributes) => { const manipulationOfNotificationAccess = device.currentNotificationAccessPermission !== device.highestNotificationAccessPermission const manipulationOfAppVersion = device.currentAppVersion !== device.highestAppVersion const manipulationOfOverlayPermission = device.currentOverlayPermission !== device.highestOverlayPermission + const manipulationOfAsPermission = device.asEnabled !== device.wasAsEnabled const hasActiveManipulationWarning = manipulationOfProtectionLevel || manipulationOfUsageStats || @@ -215,7 +234,8 @@ export const hasDeviceManipulation = (device: DeviceAttributes) => { manipulationOfAppVersion || device.triedDisablingDeviceAdmin || device.didReboot || - manipulationOfOverlayPermission + manipulationOfOverlayPermission || + manipulationOfAsPermission const hasAnyManipulation = hasActiveManipulationWarning || device.hadManipulation diff --git a/src/database/migration/migrations/20190402-add-as-permission.ts b/src/database/migration/migrations/20190402-add-as-permission.ts new file mode 100644 index 0000000..7cab24b --- /dev/null +++ b/src/database/migration/migrations/20190402-add-as-permission.ts @@ -0,0 +1,46 @@ +/* + * server component for the TimeLimit App + * Copyright (C) 2019 Jonas Lochmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { QueryInterface, Sequelize } from 'sequelize' +import { attributesVersion8 } from '../../device' + +export async function up (queryInterface: QueryInterface, sequelize: Sequelize) { + await sequelize.transaction({ + type: 'EXCLUSIVE' + }, async (transaction) => { + await queryInterface.addColumn('Devices', 'asEnabled', { + ...attributesVersion8.asEnabled + }, { + transaction + }) + + await queryInterface.addColumn('Devices', 'wasAsEnabled', { + ...attributesVersion8.wasAsEnabled + }, { + transaction + }) + }) +} + +export async function down (queryInterface: QueryInterface, sequelize: Sequelize) { + await sequelize.transaction({ + type: 'EXCLUSIVE' + }, async (transaction) => { + await queryInterface.removeColumn('Devices', 'asEnabled', { transaction }) + await queryInterface.removeColumn('Devices', 'wasAsEnabled', { transaction }) + }) +} diff --git a/src/function/device/prepare-device-entry.ts b/src/function/device/prepare-device-entry.ts index 43305f2..c7aaafd 100644 --- a/src/function/device/prepare-device-entry.ts +++ b/src/function/device/prepare-device-entry.ts @@ -57,5 +57,7 @@ export const prepareDeviceEntry = ({ familyId, userId, deviceAuthToken, deviceId defaultUserTimeout: 0, considerRebootManipulation: false, currentOverlayPermission: 'not granted', - highestOverlayPermission: 'not granted' + highestOverlayPermission: 'not granted', + asEnabled: false, + wasAsEnabled: false }) diff --git a/src/function/sync/apply-actions/dispatch-app-logic-action/updatedevicestatus.ts b/src/function/sync/apply-actions/dispatch-app-logic-action/updatedevicestatus.ts index 36229a2..a6f9235 100644 --- a/src/function/sync/apply-actions/dispatch-app-logic-action/updatedevicestatus.ts +++ b/src/function/sync/apply-actions/dispatch-app-logic-action/updatedevicestatus.ts @@ -107,6 +107,20 @@ export async function dispatchUpdateDeviceStatus ({ deviceId, action, cache }: { } } + if (action.newAccessibilityServiceEnabled !== undefined) { + const hasChanged = deviceEntry.asEnabled !== action.newAccessibilityServiceEnabled + + deviceEntry.asEnabled = action.newAccessibilityServiceEnabled + + if (action.newAccessibilityServiceEnabled) { + deviceEntry.wasAsEnabled = true + } + + if (hasChanged && (deviceEntry.asEnabled !== deviceEntry.wasAsEnabled)) { + deviceEntry.hadManipulation = true + } + } + if (action.newAppVersion !== undefined) { const hasChanged = deviceEntry.currentAppVersion !== action.newAppVersion diff --git a/src/function/sync/apply-actions/dispatch-parent-action/ignoremanipulation.ts b/src/function/sync/apply-actions/dispatch-parent-action/ignoremanipulation.ts index 2f28ea0..10b35fd 100644 --- a/src/function/sync/apply-actions/dispatch-parent-action/ignoremanipulation.ts +++ b/src/function/sync/apply-actions/dispatch-parent-action/ignoremanipulation.ts @@ -58,6 +58,10 @@ export async function dispatchIgnoreManipulation ({ action, cache }: { deviceEntry.highestOverlayPermission = deviceEntry.currentOverlayPermission } + if (action.ignoreAccessibilityServiceManipulation) { + deviceEntry.wasAsEnabled = deviceEntry.asEnabled + } + if (action.ignoreDidReboot) { deviceEntry.didReboot = false } diff --git a/src/function/sync/get-server-data-status.ts b/src/function/sync/get-server-data-status.ts index b6a9376..16a0926 100644 --- a/src/function/sync/get-server-data-status.ts +++ b/src/function/sync/get-server-data-status.ts @@ -95,7 +95,9 @@ export const generateServerDataStatus = async ({ database, clientStatus, familyI defUserTimeout: item.defaultUserTimeout, rebootIsManipulation: item.considerRebootManipulation, cOverlay: item.currentOverlayPermission, - hOverlay: item.highestOverlayPermission + hOverlay: item.highestOverlayPermission, + asEnabled: item.asEnabled, + wasAsEnabled: item.wasAsEnabled })) } } diff --git a/src/object/serverdatastatus.ts b/src/object/serverdatastatus.ts index 771e2d6..d819360 100644 --- a/src/object/serverdatastatus.ts +++ b/src/object/serverdatastatus.ts @@ -84,6 +84,8 @@ export interface ServerDeviceData { rebootIsManipulation: boolean cOverlay: RuntimePermissionStatus hOverlay: RuntimePermissionStatus + asEnabled: boolean + wasAsEnabled: boolean } export interface ServerUpdatedCategoryBaseData {