mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add security tab for server properties (#24209)
Co-authored-by: Cory Rivera <corivera@microsoft.com>
This commit is contained in:
@@ -31,6 +31,7 @@ export const CreateDatabaseDocUrl = 'https://learn.microsoft.com/sql/t-sql/state
|
|||||||
export const ViewGeneralServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/t-sql/functions/serverproperty-transact-sql';
|
export const ViewGeneralServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/t-sql/functions/serverproperty-transact-sql';
|
||||||
export const ViewMemoryServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/database-engine/configure-windows/server-properties-memory-page';
|
export const ViewMemoryServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/database-engine/configure-windows/server-properties-memory-page';
|
||||||
export const ViewProcessorsServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/database-engine/configure-windows/server-properties-processors-page';
|
export const ViewProcessorsServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/database-engine/configure-windows/server-properties-processors-page';
|
||||||
|
export const ViewSecurityServerPropertiesDocUrl = 'https://learn.microsoft.com/sql/database-engine/configure-windows/server-properties-security-page';
|
||||||
export const DetachDatabaseDocUrl = 'https://go.microsoft.com/fwlink/?linkid=2240322';
|
export const DetachDatabaseDocUrl = 'https://go.microsoft.com/fwlink/?linkid=2240322';
|
||||||
export const DatabaseGeneralPropertiesDocUrl = 'https://learn.microsoft.com/sql/relational-databases/databases/database-properties-general-page';
|
export const DatabaseGeneralPropertiesDocUrl = 'https://learn.microsoft.com/sql/relational-databases/databases/database-properties-general-page';
|
||||||
export const DatabaseOptionsPropertiesDocUrl = 'https://learn.microsoft.com/sql/relational-databases/databases/database-properties-options-page'
|
export const DatabaseOptionsPropertiesDocUrl = 'https://learn.microsoft.com/sql/relational-databases/databases/database-properties-options-page'
|
||||||
|
|||||||
@@ -538,6 +538,26 @@ export interface Server extends ObjectManagement.SqlObject {
|
|||||||
autoProcessorAffinityMaskForAll: boolean;
|
autoProcessorAffinityMaskForAll: boolean;
|
||||||
autoProcessorAffinityIOMaskForAll: boolean;
|
autoProcessorAffinityIOMaskForAll: boolean;
|
||||||
numaNodes: NumaNode[];
|
numaNodes: NumaNode[];
|
||||||
|
authenticationMode: ServerLoginMode;
|
||||||
|
loginAuditing: AuditLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server login types.
|
||||||
|
*/
|
||||||
|
export const enum ServerLoginMode {
|
||||||
|
Integrated, //windows auth only
|
||||||
|
Mixed // both sql server and windows auth
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server audit levels.
|
||||||
|
*/
|
||||||
|
export const enum AuditLevel {
|
||||||
|
None,
|
||||||
|
Success,
|
||||||
|
Failure,
|
||||||
|
All
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NumericServerProperty {
|
export interface NumericServerProperty {
|
||||||
|
|||||||
@@ -287,6 +287,16 @@ export const processorLabel = localize('objectManagement.processorLabel', "Proce
|
|||||||
export const serverMemoryMaxLowerThanMinInputError: string = localize('objectManagement.serverMemoryMaxLowerThanMinInputError', "Maximum server memory cannot be lower than minimum server memory");
|
export const serverMemoryMaxLowerThanMinInputError: string = localize('objectManagement.serverMemoryMaxLowerThanMinInputError', "Maximum server memory cannot be lower than minimum server memory");
|
||||||
export const serverNumaNodeLabel = (value: string) => localize('objectManagement.serverNumaNodeLabel', "Numa Node {0}", value);
|
export const serverNumaNodeLabel = (value: string) => localize('objectManagement.serverNumaNodeLabel', "Numa Node {0}", value);
|
||||||
export const serverCPULabel = (value: string) => localize('objectManagement.serverCPULabel', "CPU {0}", value);
|
export const serverCPULabel = (value: string) => localize('objectManagement.serverCPULabel', "CPU {0}", value);
|
||||||
|
export const securityText = localize('objectManagement.security', "Security");
|
||||||
|
export const serverAuthenticationText = localize('objectManagement.serverAuthenticationText', "Server authentication");
|
||||||
|
export const onlyWindowsAuthModeText = localize('objectManagement.onlyWindowsAuthModeText', "Windows Authentication mode");
|
||||||
|
export const sqlServerAndWindowsAuthText = localize('objectManagement.sqlServerAndWindowsAuthText', "SQL Server and Windows Authentication mode");
|
||||||
|
export const loginAuditingText = localize('objectManagement.loginAuditingText', "Login auditing");
|
||||||
|
export const noLoginAuditingText = localize('objectManagement.noLoginAuditingText', "None");
|
||||||
|
export const failedLoginsOnlyText = localize('objectManagement.failedLoginsOnlyText', "Failed logins only");
|
||||||
|
export const successfulLoginsOnlyText = localize('objectManagement.successfulLoginsOnlyText', "Successful logins only");
|
||||||
|
export const bothFailedAndSuccessfulLoginsText = localize('objectManagement.bothFailedAndSuccessfulLoginsText', "Both failed and successful logins");
|
||||||
|
export const needToRestartServer = localize('objectManagement.needToRestartServer', "Changes require server restart in order to be effective");
|
||||||
|
|
||||||
//Database properties Dialog
|
//Database properties Dialog
|
||||||
export const LastDatabaseBackupText = localize('objectManagement.lastDatabaseBackup', "Last Database Backup");
|
export const LastDatabaseBackupText = localize('objectManagement.lastDatabaseBackup', "Last Database Backup");
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
import { ObjectManagementDialogBase, ObjectManagementDialogOptions } from './objectManagementDialogBase';
|
import { ObjectManagementDialogBase, ObjectManagementDialogOptions } from './objectManagementDialogBase';
|
||||||
import { DefaultColumnCheckboxWidth } from '../../ui/dialogBase';
|
import { DefaultColumnCheckboxWidth } from '../../ui/dialogBase';
|
||||||
import { IObjectManagementService } from 'mssql';
|
import { IObjectManagementService } from 'mssql';
|
||||||
import * as localizedConstants from '../localizedConstants';
|
import * as localizedConstants from '../localizedConstants';
|
||||||
import { ViewGeneralServerPropertiesDocUrl, ViewMemoryServerPropertiesDocUrl, ViewProcessorsServerPropertiesDocUrl } from '../constants';
|
import { ViewGeneralServerPropertiesDocUrl, ViewMemoryServerPropertiesDocUrl, ViewProcessorsServerPropertiesDocUrl, ViewSecurityServerPropertiesDocUrl } from '../constants';
|
||||||
import { Server, ServerViewInfo, NumaNode, AffinityType } from '../interfaces';
|
import { Server, ServerViewInfo, NumaNode, AffinityType, ServerLoginMode, AuditLevel } from '../interfaces';
|
||||||
|
|
||||||
export class ServerPropertiesDialog extends ObjectManagementDialogBase<Server, ServerViewInfo> {
|
export class ServerPropertiesDialog extends ObjectManagementDialogBase<Server, ServerViewInfo> {
|
||||||
private generalTab: azdata.Tab;
|
private generalTab: azdata.Tab;
|
||||||
@@ -46,6 +47,19 @@ export class ServerPropertiesDialog extends ObjectManagementDialogBase<Server, S
|
|||||||
private processorsSection: azdata.GroupContainer;
|
private processorsSection: azdata.GroupContainer;
|
||||||
private autoSetProcessorAffinityMaskForAllCheckbox: azdata.CheckBoxComponent;
|
private autoSetProcessorAffinityMaskForAllCheckbox: azdata.CheckBoxComponent;
|
||||||
private autoSetProcessorIOAffinityMaskForAllCheckbox: azdata.CheckBoxComponent;
|
private autoSetProcessorIOAffinityMaskForAllCheckbox: azdata.CheckBoxComponent;
|
||||||
|
|
||||||
|
private securityTab: azdata.Tab;
|
||||||
|
private readonly securityTabId: string = 'securityId';
|
||||||
|
private securitySection: azdata.GroupContainer;
|
||||||
|
// Server authentication radio buttons
|
||||||
|
private onlyWindowsAuthRadioButton: azdata.RadioButtonComponent;
|
||||||
|
private sqlServerAndWindowsAuthRadioButton: azdata.RadioButtonComponent;
|
||||||
|
// Login auditing radio buttons
|
||||||
|
private noneRadioButton: azdata.RadioButtonComponent;
|
||||||
|
private failedLoginsOnlyRadioButton: azdata.RadioButtonComponent;
|
||||||
|
private successfulLoginsOnlyRadioButton: azdata.RadioButtonComponent;
|
||||||
|
private bothFailedAndSuccessfulLoginsRadioButton: azdata.RadioButtonComponent;
|
||||||
|
|
||||||
private activeTabId: string;
|
private activeTabId: string;
|
||||||
|
|
||||||
constructor(objectManagementService: IObjectManagementService, options: ObjectManagementDialogOptions) {
|
constructor(objectManagementService: IObjectManagementService, options: ObjectManagementDialogOptions) {
|
||||||
@@ -62,6 +76,8 @@ export class ServerPropertiesDialog extends ObjectManagementDialogBase<Server, S
|
|||||||
helpUrl = ViewMemoryServerPropertiesDocUrl;
|
helpUrl = ViewMemoryServerPropertiesDocUrl;
|
||||||
case this.processorsTabId:
|
case this.processorsTabId:
|
||||||
helpUrl = ViewProcessorsServerPropertiesDocUrl;
|
helpUrl = ViewProcessorsServerPropertiesDocUrl;
|
||||||
|
case this.securityTabId:
|
||||||
|
helpUrl = ViewSecurityServerPropertiesDocUrl;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -74,7 +90,8 @@ export class ServerPropertiesDialog extends ObjectManagementDialogBase<Server, S
|
|||||||
this.initializeGeneralSection();
|
this.initializeGeneralSection();
|
||||||
this.initializeMemorySection();
|
this.initializeMemorySection();
|
||||||
this.initializeProcessorsSection();
|
this.initializeProcessorsSection();
|
||||||
const serverPropertiesTabGroup = { title: '', tabs: [this.generalTab, this.memoryTab, this.processorsTab] };
|
this.initializeSecuritySection();
|
||||||
|
const serverPropertiesTabGroup = { title: '', tabs: [this.generalTab, this.memoryTab, this.processorsTab, this.securityTab] };
|
||||||
const serverPropertiesTabbedPannel = this.modelView.modelBuilder.tabbedPanel()
|
const serverPropertiesTabbedPannel = this.modelView.modelBuilder.tabbedPanel()
|
||||||
.withTabs([serverPropertiesTabGroup])
|
.withTabs([serverPropertiesTabGroup])
|
||||||
.withProps({
|
.withProps({
|
||||||
@@ -425,4 +442,61 @@ export class ServerPropertiesDialog extends ObjectManagementDialogBase<Server, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private initializeSecuritySection(): void {
|
||||||
|
// cannot change auth mode in sql managed instance or non windows instances
|
||||||
|
const isEnabled = this.engineEdition !== azdata.DatabaseEngineEdition.SqlManagedInstance && this.objectInfo.platform !== 'Windows';
|
||||||
|
const radioServerGroupName = 'serverAuthenticationRadioGroup';
|
||||||
|
this.onlyWindowsAuthRadioButton = this.createRadioButton(localizedConstants.onlyWindowsAuthModeText, radioServerGroupName, this.objectInfo.authenticationMode === ServerLoginMode.Integrated, async () => { await this.handleAuthModeChange(); });
|
||||||
|
this.sqlServerAndWindowsAuthRadioButton = this.createRadioButton(localizedConstants.sqlServerAndWindowsAuthText, radioServerGroupName, this.objectInfo.authenticationMode === ServerLoginMode.Mixed, async () => { await this.handleAuthModeChange(); });
|
||||||
|
this.onlyWindowsAuthRadioButton.enabled = isEnabled;
|
||||||
|
this.sqlServerAndWindowsAuthRadioButton.enabled = isEnabled;
|
||||||
|
const serverAuthSection = this.createGroup(localizedConstants.serverAuthenticationText, [
|
||||||
|
this.onlyWindowsAuthRadioButton,
|
||||||
|
this.sqlServerAndWindowsAuthRadioButton
|
||||||
|
], true);
|
||||||
|
|
||||||
|
const radioLoginsGroupName = 'serverLoginsRadioGroup';
|
||||||
|
this.noneRadioButton = this.createRadioButton(localizedConstants.noLoginAuditingText, radioLoginsGroupName, this.objectInfo.loginAuditing === AuditLevel.None, async () => { await this.handleAuditLevelChange(); });
|
||||||
|
this.failedLoginsOnlyRadioButton = this.createRadioButton(localizedConstants.failedLoginsOnlyText, radioLoginsGroupName, this.objectInfo.loginAuditing === AuditLevel.Failure, async () => { await this.handleAuditLevelChange(); });
|
||||||
|
this.successfulLoginsOnlyRadioButton = this.createRadioButton(localizedConstants.successfulLoginsOnlyText, radioLoginsGroupName, this.objectInfo.loginAuditing === AuditLevel.Success, async () => { await this.handleAuditLevelChange(); });
|
||||||
|
this.bothFailedAndSuccessfulLoginsRadioButton = this.createRadioButton(localizedConstants.bothFailedAndSuccessfulLoginsText, radioLoginsGroupName, this.objectInfo.loginAuditing === AuditLevel.All, async () => { await this.handleAuditLevelChange(); });
|
||||||
|
const serverLoginSection = this.createGroup(localizedConstants.loginAuditingText, [
|
||||||
|
this.noneRadioButton,
|
||||||
|
this.failedLoginsOnlyRadioButton,
|
||||||
|
this.successfulLoginsOnlyRadioButton,
|
||||||
|
this.bothFailedAndSuccessfulLoginsRadioButton
|
||||||
|
], true);
|
||||||
|
this.securitySection = this.createGroup('', [
|
||||||
|
serverAuthSection,
|
||||||
|
serverLoginSection
|
||||||
|
], true);
|
||||||
|
|
||||||
|
this.securityTab = this.createTab(this.securityTabId, localizedConstants.securityText, this.securitySection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleAuthModeChange(): Promise<void> {
|
||||||
|
if (this.onlyWindowsAuthRadioButton.checked) {
|
||||||
|
this.objectInfo.authenticationMode = ServerLoginMode.Integrated;
|
||||||
|
}
|
||||||
|
if (this.sqlServerAndWindowsAuthRadioButton.checked) {
|
||||||
|
this.objectInfo.authenticationMode = ServerLoginMode.Mixed;
|
||||||
|
}
|
||||||
|
await vscode.window.showInformationMessage(localizedConstants.needToRestartServer, { modal: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleAuditLevelChange(): Promise<void> {
|
||||||
|
if (this.noneRadioButton.checked) {
|
||||||
|
this.objectInfo.loginAuditing = AuditLevel.None;
|
||||||
|
}
|
||||||
|
if (this.failedLoginsOnlyRadioButton.checked) {
|
||||||
|
this.objectInfo.loginAuditing = AuditLevel.Failure;
|
||||||
|
}
|
||||||
|
if (this.successfulLoginsOnlyRadioButton.checked) {
|
||||||
|
this.objectInfo.loginAuditing = AuditLevel.Success;
|
||||||
|
}
|
||||||
|
if (this.bothFailedAndSuccessfulLoginsRadioButton.checked) {
|
||||||
|
this.objectInfo.loginAuditing = AuditLevel.All;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user