Skip to content

Commit

Permalink
Add "(Administrator)" suffix to window title when running as administ…
Browse files Browse the repository at this point in the history
…rator in Windows (fixes #19707)
  • Loading branch information
bpasero committed Dec 12, 2017
1 parent db328de commit 9f0383f
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 25 deletions.
1 change: 1 addition & 0 deletions build/gulpfile.vscode.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ function packageTask(platform, arch, opts) {
.pipe(util.cleanNodeModule('oniguruma', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/*.js']))
.pipe(util.cleanNodeModule('windows-mutex', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-is-elevated', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('jschardet', ['dist/**']))
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"jschardet": "1.6.0",
"keytar": "^4.0.5",
"minimist": "1.2.0",
"native-is-elevated": "^0.2.1",
"native-keymap": "1.2.5",
"native-watchdog": "0.3.0",
"node-pty": "0.7.4",
Expand Down
10 changes: 10 additions & 0 deletions src/typings/native-is-elevated.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

declare module 'native-is-elevated' {
function isElevated(): boolean;

export = isElevated;
}
37 changes: 22 additions & 15 deletions src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ import { Builder, $, Dimension } from 'vs/base/browser/builder';
import * as DOM from 'vs/base/browser/dom';
import * as paths from 'vs/base/common/paths';
import { Part } from 'vs/workbench/browser/part';
import { ITitleService } from 'vs/workbench/services/title/common/titleService';
import { ITitleService, ITitleProperties } from 'vs/workbench/services/title/common/titleService';
import { getZoomFactor } from 'vs/base/browser/browser';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import * as errors from 'vs/base/common/errors';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction, Action } from 'vs/base/common/actions';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
Expand All @@ -31,7 +30,7 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/
import { Verbosity } from 'vs/platform/editor/common/editor';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme';
import { isMacintosh } from 'vs/base/common/platform';
import { isMacintosh, isWindows } from 'vs/base/common/platform';
import URI from 'vs/base/common/uri';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';

Expand All @@ -40,6 +39,7 @@ export class TitlebarPart extends Part implements ITitleService {
public _serviceBrand: any;

private static readonly NLS_UNSUPPORTED = nls.localize('patchedWindowTitle', "[Unsupported]");
private static readonly NLS_USER_IS_ADMIN = isWindows ? nls.localize('userIsAdmin', "[Administrator]") : nls.localize('userIsSudo', "[Superuser]");
private static readonly NLS_EXTENSION_HOST = nls.localize('devExtensionWindowTitlePrefix', "[Extension Development Host]");
private static readonly TITLE_DIRTY = '\u25cf ';
private static readonly TITLE_SEPARATOR = isMacintosh ? ' — ' : ' - '; // macOS uses special - separator
Expand All @@ -52,7 +52,7 @@ export class TitlebarPart extends Part implements ITitleService {

private isInactive: boolean;

private isPure: boolean;
private properties: ITitleProperties;
private activeEditorListeners: IDisposable[];

constructor(
Expand All @@ -63,15 +63,14 @@ export class TitlebarPart extends Part implements ITitleService {
@IWindowsService private windowsService: IWindowsService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IEditorGroupService private editorGroupService: IEditorGroupService,
@IIntegrityService private integrityService: IIntegrityService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IThemeService themeService: IThemeService,
@ILifecycleService private lifecycleService: ILifecycleService
) {
super(id, { hasTitle: false }, themeService);

this.isPure = true;
this.properties = { isPure: true, isAdmin: false };
this.activeEditorListeners = [];

this.init();
Expand All @@ -83,14 +82,6 @@ export class TitlebarPart extends Part implements ITitleService {

// Initial window title when loading is done
this.lifecycleService.when(LifecyclePhase.Running).then(() => this.setTitle(this.getWindowTitle()));

// Integrity for window title
this.integrityService.isPure().then(r => {
if (!r.isPure) {
this.isPure = false;
this.setTitle(this.getWindowTitle());
}
});
}

private registerListeners(): void {
Expand Down Expand Up @@ -149,7 +140,11 @@ export class TitlebarPart extends Part implements ITitleService {
title = this.environmentService.appNameLong;
}

if (!this.isPure) {
if (this.properties.isAdmin) {
title = `${title} ${TitlebarPart.NLS_USER_IS_ADMIN}`;
}

if (!this.properties.isPure) {
title = `${title} ${TitlebarPart.NLS_UNSUPPORTED}`;
}

Expand All @@ -161,6 +156,18 @@ export class TitlebarPart extends Part implements ITitleService {
return title;
}

public updateProperties(properties: ITitleProperties): void {
const isAdmin = typeof properties.isAdmin === 'boolean' ? properties.isAdmin : this.properties.isAdmin;
const isPure = typeof properties.isPure === 'boolean' ? properties.isPure : this.properties.isPure;

if (isAdmin !== this.properties.isAdmin || isPure !== this.properties.isPure) {
this.properties.isAdmin = isAdmin;
this.properties.isPure = isPure;

this.setTitle(this.getWindowTitle());
}
}

/**
* Possible template values:
*
Expand Down
6 changes: 0 additions & 6 deletions src/vs/workbench/electron-browser/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import 'vs/css!./media/shell';

import * as nls from 'vs/nls';
import * as platform from 'vs/base/common/platform';
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
import dom = require('vs/base/browser/dom');
Expand Down Expand Up @@ -193,11 +192,6 @@ export class WorkbenchShell {
// Startup Telemetry
this.logStartupTelemetry(info);

// Root Warning
if ((platform.isLinux || platform.isMacintosh) && process.getuid() === 0) {
this.messageService.show(Severity.Warning, nls.localize('runningAsRoot', "It is recommended not to run Code as 'root'."));
}

// Set lifecycle phase to `Runnning` so that other contributions can now do something
this.lifecycleService.phase = LifecyclePhase.Running;

Expand Down
39 changes: 35 additions & 4 deletions src/vs/workbench/electron-browser/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
'use strict';

import nls = require('vs/nls');
import platform = require('vs/base/common/platform');
import URI from 'vs/base/common/uri';
import errors = require('vs/base/common/errors');
import types = require('vs/base/common/types');
Expand Down Expand Up @@ -46,6 +45,9 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces';
import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
import { AccessibilitySupport, isRootUser, isWindows, isMacintosh } from 'vs/base/common/platform';
import product from 'vs/platform/node/product';

const TextInputActions: IAction[] = [
new Action('undo', nls.localize('undo', "Undo"), null, true, () => document.execCommand('undo') && TPromise.as(true)),
Expand Down Expand Up @@ -91,7 +93,8 @@ export class ElectronWindow extends Themable {
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
@IFileService private fileService: IFileService,
@IMenuService private menuService: IMenuService,
@ILifecycleService private lifecycleService: ILifecycleService
@ILifecycleService private lifecycleService: ILifecycleService,
@IIntegrityService private integrityService: IIntegrityService
) {
super(themeService);

Expand Down Expand Up @@ -239,7 +242,7 @@ export class ElectronWindow extends Themable {

// keyboard layout changed event
ipc.on('vscode:accessibilitySupportChanged', (_event: any, accessibilitySupportEnabled: boolean) => {
browser.setAccessibilitySupport(accessibilitySupportEnabled ? platform.AccessibilitySupport.Enabled : platform.AccessibilitySupport.Disabled);
browser.setAccessibilitySupport(accessibilitySupportEnabled ? AccessibilitySupport.Enabled : AccessibilitySupport.Disabled);
});

// Zoom level changes
Expand Down Expand Up @@ -317,10 +320,38 @@ export class ElectronWindow extends Themable {

// Touchbar Support
this.updateTouchbarMenu();

// Integrity warning
this.integrityService.isPure().then(res => this.titleService.updateProperties({ isPure: res.isPure }));

// Root warning
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
let isAdminPromise: Promise<boolean>;
if (isWindows) {
isAdminPromise = import('native-is-elevated').then(isElevated => isElevated());
} else {
isAdminPromise = Promise.resolve(isRootUser);
}

return isAdminPromise.then(isAdmin => {

// Update title
this.titleService.updateProperties({ isAdmin });

// Show warning message
if (isAdmin) {
if (isWindows) {
this.messageService.show(Severity.Warning, nls.localize('runningAsAdmin', "It is not recommended to run {0} as Administrator.", product.nameShort));
} else {
this.messageService.show(Severity.Warning, nls.localize('runningAsRoot', "It is not recommended to run {0} as root user.", product.nameShort));
}
}
});
});
}

private updateTouchbarMenu(): void {
if (!platform.isMacintosh) {
if (!isMacintosh) {
return; // macOS only
}

Expand Down
10 changes: 10 additions & 0 deletions src/vs/workbench/services/title/common/titleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'

export const ITitleService = createDecorator<ITitleService>('titleService');

export interface ITitleProperties {
isPure?: boolean;
isAdmin?: boolean;
}

export interface ITitleService {
_serviceBrand: any;

Expand All @@ -20,4 +25,9 @@ export interface ITitleService {
* Set the represented file name to the title if any.
*/
setRepresentedFilename(path: string): void;

/**
* Update some environmental title properties.
*/
updateProperties(properties: ITitleProperties): void;
}
4 changes: 4 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3742,6 +3742,10 @@ nan@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"

native-is-elevated@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.2.1.tgz#70a2123a8575b9f624a3ef465d98cb74ae017385"

[email protected]:
version "1.2.5"
resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-1.2.5.tgz#1035a9417b9a9340cf8097763a43c76d588165a5"
Expand Down

0 comments on commit 9f0383f

Please sign in to comment.