mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Fix CMS password login issues (#21260)
This commit is contained in:
@@ -36,12 +36,6 @@ export class CmsResourceTreeNode extends CmsResourceTreeNodeBase {
|
|||||||
public async getChildren(): Promise<TreeNode[]> {
|
public async getChildren(): Promise<TreeNode[]> {
|
||||||
try {
|
try {
|
||||||
let nodes: CmsResourceTreeNodeBase[] = [];
|
let nodes: CmsResourceTreeNodeBase[] = [];
|
||||||
if (!this.ownerUri) {
|
|
||||||
// Set back password to get ownerUri
|
|
||||||
if (this.connection.options.authenticationType === azdata.connection.AuthenticationType.SqlLogin && this.connection.options.savePassword === true) {
|
|
||||||
this.connection.options.password = await this.appContext.cmsUtils.getPassword(this.connection.options.user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.appContext.cmsUtils.createCmsServer(this.connection, this.name, this.description).then(async (result) => {
|
return this.appContext.cmsUtils.createCmsServer(this.connection, this.name, this.description).then(async (result) => {
|
||||||
// update the owner uri and the connection
|
// update the owner uri and the connection
|
||||||
this._ownerUri = result.ownerUri;
|
this._ownerUri = result.ownerUri;
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ const cmsProvider: string = 'MSSQL-CMS';
|
|||||||
const mssqlProvider: string = 'MSSQL';
|
const mssqlProvider: string = 'MSSQL';
|
||||||
const CredentialNamespace = 'cmsCredentials';
|
const CredentialNamespace = 'cmsCredentials';
|
||||||
|
|
||||||
|
const CRED_PREFIX = 'Microsoft.SqlTools';
|
||||||
|
const CRED_SEPARATOR = '|';
|
||||||
|
const CRED_KEYVALUE_SEPARATOR = ':';
|
||||||
|
const CRED_ID_PREFIX = 'id:';
|
||||||
|
const CRED_ITEMTYPE_PREFIX = 'itemtype:';
|
||||||
|
const CRED_PROFILE_USER = 'Profile';
|
||||||
|
|
||||||
interface CreateCmsResult {
|
interface CreateCmsResult {
|
||||||
listRegisteredServersResult: mssql.ListRegisteredServersResult;
|
listRegisteredServersResult: mssql.ListRegisteredServersResult;
|
||||||
connection: azdata.connection.Connection;
|
connection: azdata.connection.Connection;
|
||||||
@@ -31,17 +38,32 @@ export class CmsUtils {
|
|||||||
private _cmsService: mssql.ICmsService;
|
private _cmsService: mssql.ICmsService;
|
||||||
private _registeredCmsServers: ICmsResourceNodeInfo[] = [];
|
private _registeredCmsServers: ICmsResourceNodeInfo[] = [];
|
||||||
|
|
||||||
// [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Used for unit testing, not actual valid credential")]
|
public async savePassword(credId: string, password: string): Promise<boolean> {
|
||||||
public async savePassword(username: string, password: string): Promise<boolean> {
|
|
||||||
let provider = await this.credentialProvider();
|
let provider = await this.credentialProvider();
|
||||||
let result = await provider.saveCredential(username, password);
|
let result = await provider.saveCredential(credId, password);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getPassword(username: string): Promise<string> {
|
public async getPassword(connection: azdata.connection.Connection): Promise<string | undefined> {
|
||||||
let provider = await this.credentialProvider();
|
let provider = await this.credentialProvider();
|
||||||
let credential = await provider.readCredential(username);
|
let credId = this.formatCredentialId(connection);
|
||||||
return credential ? credential.password : undefined;
|
let credential = await provider.readCredential(credId);
|
||||||
|
return credential?.password ? credential.password : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a formatted credential usable for uniquely identifying a SQL Connection.
|
||||||
|
* This string can be decoded but is not optimized for this.
|
||||||
|
* @param connection connection instance - required
|
||||||
|
* @returns formatted string with server, DB and username
|
||||||
|
*/
|
||||||
|
private formatCredentialId(connection: azdata.connection.Connection): string {
|
||||||
|
const cred: string[] = [CRED_PREFIX];
|
||||||
|
cred.push(CRED_ITEMTYPE_PREFIX.concat(CRED_PROFILE_USER));
|
||||||
|
cred.push('Server' + CRED_KEYVALUE_SEPARATOR + CRED_ID_PREFIX.concat(connection.options.server));
|
||||||
|
cred.push('Database' + CRED_KEYVALUE_SEPARATOR + CRED_ID_PREFIX.concat(connection.options.database));
|
||||||
|
cred.push('User' + CRED_KEYVALUE_SEPARATOR + CRED_ID_PREFIX.concat(connection.options.user));
|
||||||
|
return cred.join(CRED_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSavedServers(): ICmsResourceNodeInfo[] {
|
public getSavedServers(): ICmsResourceNodeInfo[] {
|
||||||
@@ -56,7 +78,9 @@ export class CmsUtils {
|
|||||||
let ownerUri = await azdata.connection.getUriForConnection(connection.connectionId);
|
let ownerUri = await azdata.connection.getUriForConnection(connection.connectionId);
|
||||||
if (!ownerUri) {
|
if (!ownerUri) {
|
||||||
// Make a connection if it's not already connected
|
// Make a connection if it's not already connected
|
||||||
let result = await azdata.connection.connect(Utils.toConnectionProfile(connection), false, false);
|
let profile = Utils.toConnectionProfile(connection);
|
||||||
|
profile.password = await this.getPassword(connection);
|
||||||
|
let result = await azdata.connection.connect(profile, false, false);
|
||||||
if (result) {
|
if (result) {
|
||||||
ownerUri = await azdata.connection.getUriForConnection(result.connectionId);
|
ownerUri = await azdata.connection.getUriForConnection(result.connectionId);
|
||||||
}
|
}
|
||||||
@@ -85,6 +109,10 @@ export class CmsUtils {
|
|||||||
name: string, description: string): Promise<CreateCmsResult> {
|
name: string, description: string): Promise<CreateCmsResult> {
|
||||||
let provider = await this.getCmsService();
|
let provider = await this.getCmsService();
|
||||||
connection.providerName = connection.providerName === cmsProvider ? mssqlProvider : connection.providerName;
|
connection.providerName = connection.providerName === cmsProvider ? mssqlProvider : connection.providerName;
|
||||||
|
// Populate password if it's a SQL Login mode.
|
||||||
|
if (connection.options.authenticationType === azdata.connection.AuthenticationType.SqlLogin && connection.options.savePassword) {
|
||||||
|
connection.options.password = await this.getPassword(connection);
|
||||||
|
}
|
||||||
let ownerUri = await azdata.connection.getUriForConnection(connection.connectionId);
|
let ownerUri = await azdata.connection.getUriForConnection(connection.connectionId);
|
||||||
if (!ownerUri) {
|
if (!ownerUri) {
|
||||||
// Make a connection if it's not already connected
|
// Make a connection if it's not already connected
|
||||||
@@ -121,7 +149,7 @@ export class CmsUtils {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (connection.options.authenticationType === azdata.connection.AuthenticationType.SqlLogin && connection.options.savePassword) {
|
if (connection.options.authenticationType === azdata.connection.AuthenticationType.SqlLogin && connection.options.savePassword) {
|
||||||
this._credentialProvider.deleteCredential(connection.options.user);
|
this._credentialProvider.deleteCredential(this.formatCredentialId(connection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +235,11 @@ export class CmsUtils {
|
|||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
public get registeredCmsServers(): ICmsResourceNodeInfo[] {
|
public get registeredCmsServers(): ICmsResourceNodeInfo[] {
|
||||||
|
this._registeredCmsServers.forEach(async server => {
|
||||||
|
if (server.connection.options.authenticationType === azdata.connection.AuthenticationType.SqlLogin) {
|
||||||
|
server.connection.options.password = await this.getPassword(server.connection);
|
||||||
|
}
|
||||||
|
});
|
||||||
return this._registeredCmsServers;
|
return this._registeredCmsServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,10 +272,10 @@ export class CmsUtils {
|
|||||||
if (connection) {
|
if (connection) {
|
||||||
// remove group ID from connection if a user chose connection
|
// remove group ID from connection if a user chose connection
|
||||||
// from the recent connections list
|
// from the recent connections list
|
||||||
connection.options['groupId'] = null;
|
connection.options['groupId'] = undefined;
|
||||||
connection.providerName = mssqlProvider;
|
connection.providerName = mssqlProvider;
|
||||||
if (connection.options.savePassword) {
|
if (connection.options.savePassword) {
|
||||||
await this.savePassword(connection.options.user, connection.options.password);
|
await this.savePassword(this.formatCredentialId(connection), connection.options.password);
|
||||||
}
|
}
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
@@ -250,7 +283,6 @@ export class CmsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Static Functions
|
// Static Functions
|
||||||
|
|
||||||
public getConnectionProfile(connection: azdata.connection.Connection): azdata.IConnectionProfile {
|
public getConnectionProfile(connection: azdata.connection.Connection): azdata.IConnectionProfile {
|
||||||
let connectionProfile: azdata.IConnectionProfile = {
|
let connectionProfile: azdata.IConnectionProfile = {
|
||||||
connectionName: connection.options.connectionName,
|
connectionName: connection.options.connectionName,
|
||||||
@@ -269,5 +301,4 @@ export class CmsUtils {
|
|||||||
};
|
};
|
||||||
return connectionProfile;
|
return connectionProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user