feat: Handle privilege escalation gracefully even without PolicyKit (#599)

* feat: Handle privilege escalation gracefully even without PolicyKit

* build: upgrade tslint => 5.9.1

* build: add uhk-agent/package-lock.json

* feat: add error animation

* fix: display agent icon when user use ALT + TAB
This commit is contained in:
Róbert Kiss
2018-04-07 23:09:47 +02:00
committed by László Monda
parent 6e1f0ded9e
commit 6ccf005750
22 changed files with 1680 additions and 85 deletions

View File

@@ -2,7 +2,7 @@
/// <reference path="./custom_types/command-line-args.d.ts"/>
import './polyfills';
import { app, BrowserWindow, ipcMain } from 'electron';
import { app, BrowserWindow } from 'electron';
import { autoUpdater } from 'electron-updater';
import * as path from 'path';
@@ -10,7 +10,7 @@ import * as url from 'url';
import * as commandLineArgs from 'command-line-args';
import { UhkHidDevice, UhkOperations } from 'uhk-usb';
// import { ElectronDataStorageRepositoryService } from './services/electron-datastorage-repository.service';
import { LogRegExps } from 'uhk-common';
import { CommandLineArgs, LogRegExps } from 'uhk-common';
import { DeviceService } from './services/device.service';
import { logger } from './services/logger.service';
import { AppUpdateService } from './services/app-update.service';
@@ -18,13 +18,13 @@ import { AppService } from './services/app.service';
import { SudoService } from './services/sudo.service';
import { UhkBlhost } from '../../uhk-usb/src';
import * as isDev from 'electron-is-dev';
import { CommandLineInputs } from './models/command-line-inputs';
const optionDefinitions = [
{name: 'addons', type: Boolean}
{name: 'addons', type: Boolean},
{name: 'spe', type: Boolean} // simulate privilege escalation error
];
const options: CommandLineInputs = commandLineArgs(optionDefinitions);
const options: CommandLineArgs = commandLineArgs(optionDefinitions);
// import './dev-extension';
// require('electron-debug')({ showDevTools: true, enabled: true });
@@ -83,13 +83,13 @@ function createWindow() {
});
win.setMenuBarVisibility(false);
win.maximize();
uhkHidDeviceService = new UhkHidDevice(logger);
uhkHidDeviceService = new UhkHidDevice(logger, options);
uhkBlhost = new UhkBlhost(logger, packagesDir);
uhkOperations = new UhkOperations(logger, uhkBlhost, uhkHidDeviceService, packagesDir);
deviceService = new DeviceService(logger, win, uhkHidDeviceService, uhkOperations);
appUpdateService = new AppUpdateService(logger, win, app);
appService = new AppService(logger, win, deviceService, options, uhkHidDeviceService);
sudoService = new SudoService(logger);
sudoService = new SudoService(logger, options);
// and load the index.html of the app.
win.loadURL(url.format({

View File

@@ -1,3 +1,10 @@
export interface CommandLineInputs {
/**
* addons menu visible or not
*/
addons?: boolean;
/**
* simulate privilege escalation error
*/
spe?: boolean;
}

View File

@@ -5,12 +5,13 @@ import * as sudo from 'sudo-prompt';
import { dirSync } from 'tmp';
import { emptyDir, copy } from 'fs-extra';
import { IpcEvents, LogService, IpcResponse } from 'uhk-common';
import { CommandLineArgs, IpcEvents, LogService, IpcResponse } from 'uhk-common';
export class SudoService {
private rootDir: string;
constructor(private logService: LogService) {
constructor(private logService: LogService,
private options: CommandLineArgs) {
if (isDev) {
this.rootDir = path.join(path.join(process.cwd(), process.argv[1]), '../../../../');
} else {
@@ -21,6 +22,19 @@ export class SudoService {
}
private async setPrivilege(event: Electron.Event) {
if (this.options.spe) {
const error = new Error('No polkit authentication agent found.');
this.logService.error('[SudoService] Simulate privilege escalation error ', error);
const response = new IpcResponse();
response.success = false;
response.error = {message: error.message};
event.sender.send(IpcEvents.device.setPrivilegeOnLinuxReply, response);
return;
}
switch (process.platform) {
case 'linux':
await this.setPrivilegeOnLinux(event);
@@ -28,7 +42,7 @@ export class SudoService {
default:
const response: IpcResponse = {
success: false,
error: { message: 'Permissions couldn\'t be set. Invalid platform: ' + process.platform }
error: {message: 'Permissions couldn\'t be set. Invalid platform: ' + process.platform}
};
event.sender.send(IpcEvents.device.setPrivilegeOnLinuxReply, response);
@@ -39,7 +53,7 @@ export class SudoService {
private async setPrivilegeOnLinux(event: Electron.Event) {
const tmpDirectory = dirSync();
const rulesDir = path.join(this.rootDir, 'rules');
this.logService.debug('[SudoService] Copy rules dir', { src: rulesDir, dst: tmpDirectory.name });
this.logService.debug('[SudoService] Copy rules dir', {src: rulesDir, dst: tmpDirectory.name});
await copy(rulesDir, tmpDirectory.name);
const scriptPath = path.join(tmpDirectory.name, 'setup-rules.sh');
@@ -55,7 +69,7 @@ export class SudoService {
if (error) {
this.logService.error('[SudoService] Error when set privilege: ', error);
response.success = false;
response.error = error;
response.error = {message: error.message};
} else {
response.success = true;
}