mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
CMS - SQL Login (#5989)
* initial SQL Login with save password working * fix switching auth types * remove metadata from package file * allow editing connections for unsaved password connections * review comments * change thenables to async/awaits * review comments * changed thenables to promises * remove authTypeChanged bool * removed unused import * review comments * removed try catches * cr comments * review comments
This commit is contained in:
@@ -14,6 +14,14 @@ import { ICmsResourceNodeInfo } from './cmsResource/tree/baseTreeNodes';
|
||||
const localize = nls.loadMessageBundle();
|
||||
const cmsProvider: string = 'MSSQL-CMS';
|
||||
const mssqlProvider: string = 'MSSQL';
|
||||
const CredentialNamespace = 'cmsCredentials';
|
||||
const sqlLoginAuthType: string = 'SqlLogin';
|
||||
|
||||
export interface CreateCmsResult {
|
||||
listRegisteredServersResult: mssql.ListRegisteredServersResult;
|
||||
connection: azdata.connection.Connection;
|
||||
ownerUri: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class to act as a facade over VSCode and Data APIs and allow us to test / mock callbacks into
|
||||
@@ -24,8 +32,21 @@ const mssqlProvider: string = 'MSSQL';
|
||||
*/
|
||||
export class CmsUtils {
|
||||
|
||||
private _credentialProvider: azdata.CredentialProvider;
|
||||
private _cmsService: mssql.CmsService;
|
||||
private _registeredCmsServers: ICmsResourceNodeInfo[];
|
||||
private _registeredCmsServers: ICmsResourceNodeInfo[] = [];
|
||||
|
||||
public async savePassword(username: string, password: string): Promise<boolean> {
|
||||
let provider = await this.credentialProvider();
|
||||
let result = await provider.saveCredential(username, password);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async getPassword(username: string): Promise<string> {
|
||||
let provider = await this.credentialProvider();
|
||||
let credential = await provider.readCredential(username);
|
||||
return credential ? credential.password : undefined;
|
||||
}
|
||||
|
||||
public showErrorMessage(message: string, ...items: string[]): Thenable<string | undefined> {
|
||||
return vscode.window.showErrorMessage(message, ...items);
|
||||
@@ -53,9 +74,10 @@ export class CmsUtils {
|
||||
let ownerUri = await azdata.connection.getUriForConnection(connection.connectionId);
|
||||
if (!ownerUri) {
|
||||
// Make a connection if it's not already connected
|
||||
await azdata.connection.connect(Utils.toConnectionProfile(connection), false, false).then(async (result) => {
|
||||
let result = await azdata.connection.connect(Utils.toConnectionProfile(connection), false, false);
|
||||
if (result) {
|
||||
ownerUri = await azdata.connection.getUriForConnection(result.connectionId);
|
||||
});
|
||||
}
|
||||
}
|
||||
return ownerUri;
|
||||
}
|
||||
@@ -70,59 +92,79 @@ export class CmsUtils {
|
||||
}
|
||||
|
||||
public async getRegisteredServers(ownerUri: string, relativePath: string): Promise<mssql.ListRegisteredServersResult> {
|
||||
return this.getCmsService().then((service) => {
|
||||
return service.getRegisteredServers(ownerUri, relativePath).then((result) => {
|
||||
if (result && result.registeredServersList && result.registeredServersList) {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
});
|
||||
const cmsService = await this.getCmsService();
|
||||
const result = await cmsService.getRegisteredServers(ownerUri, relativePath);
|
||||
if (result && result.registeredServersList && result.registeredServersList) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public async createCmsServer(connection: azdata.connection.Connection,
|
||||
name: string, description: string): Promise<mssql.ListRegisteredServersResult> {
|
||||
name: string, description: string): Promise<CreateCmsResult> {
|
||||
let provider = await this.getCmsService();
|
||||
connection.providerName = connection.providerName === cmsProvider ? mssqlProvider : connection.providerName;
|
||||
let ownerUri = await azdata.connection.getUriForConnection(connection.connectionId);
|
||||
if (!ownerUri) {
|
||||
// Make a connection if it's not already connected
|
||||
await azdata.connection.connect(Utils.toConnectionProfile(connection), false, false).then(async (result) => {
|
||||
ownerUri = await azdata.connection.getUriForConnection(result.connectionId);
|
||||
});
|
||||
}
|
||||
return provider.createCmsServer(name, description, connection, ownerUri).then((result) => {
|
||||
if (result) {
|
||||
return Promise.resolve(result);
|
||||
} else {
|
||||
return Promise.reject(null);
|
||||
let initialConnectionProfile = this.getConnectionProfile(connection);
|
||||
let result = await azdata.connection.connect(initialConnectionProfile, false, false);
|
||||
ownerUri = await azdata.connection.getUriForConnection(result.connectionId);
|
||||
// If the ownerUri is still undefined, then open a connection dialog with the connection
|
||||
if (!ownerUri) {
|
||||
let result = await this.makeConnection(initialConnectionProfile);
|
||||
if (result) {
|
||||
ownerUri = await azdata.connection.getUriForConnection(result.connectionId);
|
||||
connection = result;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
let result = await provider.createCmsServer(name, description, connection, ownerUri);
|
||||
const createCmsResult: CreateCmsResult = {
|
||||
listRegisteredServersResult: result,
|
||||
connection: connection,
|
||||
ownerUri: ownerUri
|
||||
};
|
||||
return createCmsResult;
|
||||
}
|
||||
|
||||
public async deleteCmsServer(cmsServer: any): Promise<void> {
|
||||
public async deleteCmsServer(cmsServerName: string, connection: azdata.connection.Connection): Promise<void> {
|
||||
let config = this.getConfiguration();
|
||||
if (config && config.servers) {
|
||||
let newServers = config.servers.filter((cachedServer) => {
|
||||
return cachedServer.name !== cmsServer;
|
||||
return cachedServer.name !== cmsServerName;
|
||||
});
|
||||
await this.setConfiguration(newServers);
|
||||
this._registeredCmsServers = this._registeredCmsServers.filter((cachedServer) => {
|
||||
return cachedServer.name !== cmsServer;
|
||||
return cachedServer.name !== cmsServerName;
|
||||
});
|
||||
}
|
||||
if (connection.options.authenticationType === sqlLoginAuthType && connection.options.savePassword) {
|
||||
this._credentialProvider.deleteCredential(connection.options.user);
|
||||
}
|
||||
}
|
||||
|
||||
public cacheRegisteredCmsServer(name: string, description: string, ownerUri: string, connection: azdata.connection.Connection): void {
|
||||
if (!this._registeredCmsServers) {
|
||||
this._registeredCmsServers = [];
|
||||
}
|
||||
public async cacheRegisteredCmsServer(name: string, description: string, ownerUri: string, connection: azdata.connection.Connection): Promise<void> {
|
||||
let cmsServerNode: ICmsResourceNodeInfo = {
|
||||
name: name,
|
||||
description: description,
|
||||
connection: connection,
|
||||
ownerUri: ownerUri
|
||||
};
|
||||
|
||||
// update a server if a server with same name exists
|
||||
this._registeredCmsServers = this._registeredCmsServers.filter((server) => {
|
||||
return server.name !== name;
|
||||
});
|
||||
this._registeredCmsServers.push(cmsServerNode);
|
||||
|
||||
// save the CMS Servers for future use
|
||||
let toSaveCmsServers: ICmsResourceNodeInfo[] = this._registeredCmsServers.map(server => Object.assign({}, server));
|
||||
toSaveCmsServers.forEach(server => {
|
||||
server.ownerUri = undefined;
|
||||
// don't save password in config
|
||||
server.connection.options.password = '';
|
||||
});
|
||||
await this.setConfiguration(toSaveCmsServers);
|
||||
}
|
||||
|
||||
public async addRegisteredServer(relativePath: string, ownerUri: string,
|
||||
@@ -143,47 +185,41 @@ export class CmsUtils {
|
||||
providerName: undefined,
|
||||
saveProfile: undefined,
|
||||
id: undefined,
|
||||
options: {}
|
||||
};
|
||||
return this.openConnectionDialog([cmsProvider], initialProfile, { saveConnection: false }).then(async (connection) => {
|
||||
if (connection && connection.options) {
|
||||
if (connection.options.server === parentServerName) {
|
||||
// error out for same server registration
|
||||
let errorText = localize('cms.errors.sameServerUnderCms', 'You cannot add a shared registered server with the same name as the Configuration Server');
|
||||
this.showErrorMessage(errorText);
|
||||
return false;
|
||||
} else {
|
||||
let registeredServerName = connection.options.registeredServerName === '' ? connection.options.server : connection.options.registeredServerName;
|
||||
let result = await provider.addRegisteredServer(ownerUri, relativePath, registeredServerName, connection.options.registeredServerDescription, connection);
|
||||
if (result) {
|
||||
return Promise.resolve(result);
|
||||
} else {
|
||||
return Promise.reject(registeredServerName);
|
||||
}
|
||||
}
|
||||
options: {
|
||||
authTypeChanged: true
|
||||
}
|
||||
});
|
||||
};
|
||||
let connection = await this.openConnectionDialog([cmsProvider], initialProfile, { saveConnection: false });
|
||||
if (connection && connection.options) {
|
||||
if (connection.options.server === parentServerName) {
|
||||
// error out for same server registration
|
||||
let errorText = localize('cms.errors.sameServerUnderCms', 'You cannot add a shared registered server with the same name as the Configuration Server');
|
||||
this.showErrorMessage(errorText);
|
||||
throw new Error(errorText);
|
||||
} else {
|
||||
let registeredServerName = connection.options.registeredServerName === '' ? connection.options.server : connection.options.registeredServerName;
|
||||
let result = await provider.addRegisteredServer(ownerUri, relativePath, registeredServerName, connection.options.registeredServerDescription, connection);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async removeRegisteredServer(registeredServerName: string, relativePath: string, ownerUri: string): Promise<boolean> {
|
||||
let provider = await this.getCmsService();
|
||||
return provider.removeRegisteredServer(ownerUri, relativePath, registeredServerName).then((result) => {
|
||||
return result;
|
||||
});
|
||||
let result = await provider.removeRegisteredServer(ownerUri, relativePath, registeredServerName);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async addServerGroup(groupName: string, groupDescription: string, relativePath: string, ownerUri: string): Promise<boolean> {
|
||||
let provider = await this.getCmsService();
|
||||
return provider.addServerGroup(ownerUri, relativePath, groupName, groupDescription).then((result) => {
|
||||
return result;
|
||||
});
|
||||
let result = await provider.addServerGroup(ownerUri, relativePath, groupName, groupDescription);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async removeServerGroup(groupName: string, relativePath: string, ownerUri: string): Promise<boolean> {
|
||||
let provider = await this.getCmsService();
|
||||
return provider.removeServerGroup(ownerUri, relativePath, groupName).then((result) => {
|
||||
return result;
|
||||
});
|
||||
let result = await provider.removeServerGroup(ownerUri, relativePath, groupName);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Getters
|
||||
@@ -191,15 +227,68 @@ export class CmsUtils {
|
||||
return this._registeredCmsServers;
|
||||
}
|
||||
|
||||
public get connection(): Thenable<azdata.connection.Connection> {
|
||||
return this.openConnectionDialog([cmsProvider], undefined, { saveConnection: false }).then((connection) => {
|
||||
if (connection) {
|
||||
// remove group ID from connection if a user chose connection
|
||||
// from the recent connections list
|
||||
connection.options['groupId'] = null;
|
||||
connection.providerName = mssqlProvider;
|
||||
return connection;
|
||||
}
|
||||
});
|
||||
public async credentialProvider(): Promise<azdata.CredentialProvider> {
|
||||
if (!this._credentialProvider) {
|
||||
this._credentialProvider = await azdata.credentials.getProvider(CredentialNamespace);
|
||||
}
|
||||
return this._credentialProvider;
|
||||
}
|
||||
|
||||
public async makeConnection(initialConnectionProfile?: azdata.IConnectionProfile): Promise<azdata.connection.Connection> {
|
||||
if (!initialConnectionProfile) {
|
||||
initialConnectionProfile = {
|
||||
connectionName: undefined,
|
||||
serverName: undefined,
|
||||
databaseName: undefined,
|
||||
userName: undefined,
|
||||
password: undefined,
|
||||
authenticationType: undefined,
|
||||
savePassword: undefined,
|
||||
groupFullName: undefined,
|
||||
groupId: undefined,
|
||||
providerName: undefined,
|
||||
saveProfile: undefined,
|
||||
id: undefined,
|
||||
options: {}
|
||||
};
|
||||
}
|
||||
let connection = await this.openConnectionDialog([cmsProvider], initialConnectionProfile, { saveConnection: false });
|
||||
if (connection) {
|
||||
// remove group ID from connection if a user chose connection
|
||||
// from the recent connections list
|
||||
connection.options['groupId'] = null;
|
||||
connection.providerName = mssqlProvider;
|
||||
if (connection.options.savePassword) {
|
||||
await this.savePassword(connection.options.user, connection.options.password);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
// Static Functions
|
||||
|
||||
public getConnectionProfile(connection: azdata.connection.Connection): azdata.IConnectionProfile {
|
||||
let connectionProfile: azdata.IConnectionProfile = {
|
||||
connectionName: connection.options.connectionName,
|
||||
serverName: connection.options.server,
|
||||
databaseName: undefined,
|
||||
userName: connection.options.user,
|
||||
password: connection.options.password,
|
||||
authenticationType: connection.options.authenticationType,
|
||||
savePassword: connection.options.savePassword,
|
||||
groupFullName: undefined,
|
||||
groupId: undefined,
|
||||
providerName: connection.providerName,
|
||||
saveProfile: false,
|
||||
id: connection.connectionId,
|
||||
options: connection.options
|
||||
};
|
||||
return connectionProfile;
|
||||
}
|
||||
|
||||
public didConnectionChange(connectionA: azdata.connection.Connection, connectionB: azdata.connection.Connection): boolean {
|
||||
return (connectionA !== connectionB) || ((connectionA.connectionId === connectionB.connectionId) &&
|
||||
(connectionA.options.savePassword !== connectionA.options.savePassword));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user