mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Implement a no sync rule (#7216)
* implement a no sync rule * fix linting disable * fix unused imports * exclude more testing * clean up fs usage * clean up more fs usage * remove duplicate of code * fix compile errors
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
import * as adal from 'adal-node';
|
||||
import * as azdata from 'azdata';
|
||||
import * as crypto from 'crypto';
|
||||
import * as fs from 'fs';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
export default class TokenCache implements adal.TokenCache {
|
||||
private static CipherAlgorithm = 'aes-256-cbc';
|
||||
@@ -58,23 +58,19 @@ export default class TokenCache implements adal.TokenCache {
|
||||
});
|
||||
}
|
||||
|
||||
public clear(): Thenable<void> {
|
||||
let self = this;
|
||||
public async clear(): Promise<void> {
|
||||
|
||||
// 1) Delete encrypted serialization file
|
||||
// If we got an 'ENOENT' response, the file doesn't exist, which is fine
|
||||
// 3) Delete the encryption key
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
fs.unlink(self._cacheSerializationPath, err => {
|
||||
if (err && err.code !== 'ENOENT') {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => { return self._credentialProvider.deleteCredential(self._credentialServiceKey); })
|
||||
.then(() => { });
|
||||
try {
|
||||
await fs.unlink(this._cacheSerializationPath);
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
await this._credentialProvider.deleteCredential(this._credentialServiceKey);
|
||||
}
|
||||
|
||||
public find(query: any, callback: (error: Error, results: any[]) => void): void {
|
||||
@@ -230,7 +226,7 @@ export default class TokenCache implements adal.TokenCache {
|
||||
});
|
||||
}
|
||||
|
||||
private readCache(): Thenable<adal.TokenResponse[]> {
|
||||
private async readCache(): Promise<adal.TokenResponse[]> {
|
||||
let self = this;
|
||||
|
||||
// NOTE: File system operations are performed synchronously to avoid annoying nested callbacks
|
||||
@@ -239,13 +235,13 @@ export default class TokenCache implements adal.TokenCache {
|
||||
// 3) Decrypt the file contents
|
||||
// 4) Deserialize and return
|
||||
return this.getOrCreateEncryptionParams()
|
||||
.then(encryptionParams => {
|
||||
.then(async encryptionParams => {
|
||||
try {
|
||||
return self.decryptCache('utf8', encryptionParams);
|
||||
} catch (e) {
|
||||
try {
|
||||
// try to parse using 'binary' encoding and rewrite cache as UTF8
|
||||
let response = self.decryptCache('binary', encryptionParams);
|
||||
let response = await self.decryptCache('binary', encryptionParams);
|
||||
self.writeCache(response);
|
||||
return response;
|
||||
} catch (e) {
|
||||
@@ -260,17 +256,17 @@ export default class TokenCache implements adal.TokenCache {
|
||||
});
|
||||
}
|
||||
|
||||
private decryptCache(encoding: crypto.Utf8AsciiBinaryEncoding, encryptionParams: EncryptionParams): adal.TokenResponse[] {
|
||||
let cacheCipher = fs.readFileSync(this._cacheSerializationPath, TokenCache.FsOptions);
|
||||
private async decryptCache(encoding: crypto.Utf8AsciiBinaryEncoding, encryptionParams: EncryptionParams): Promise<adal.TokenResponse[]> {
|
||||
let cacheCipher = await fs.readFile(this._cacheSerializationPath, TokenCache.FsOptions);
|
||||
let decipher = crypto.createDecipheriv(TokenCache.CipherAlgorithm, encryptionParams.key, encryptionParams.initializationVector);
|
||||
let cacheJson = decipher.update(cacheCipher, 'hex', encoding);
|
||||
let cacheJson = decipher.update(cacheCipher.toString(), 'hex', encoding);
|
||||
cacheJson += decipher.final(encoding);
|
||||
|
||||
// Deserialize the JSON into the array of tokens
|
||||
let cacheObj = <adal.TokenResponse[]>JSON.parse(cacheJson);
|
||||
for (let objIndex in cacheObj) {
|
||||
for (const obj of cacheObj) {
|
||||
// Rehydrate Date objects since they will always serialize as a string
|
||||
cacheObj[objIndex].expiresOn = new Date(<string>cacheObj[objIndex].expiresOn);
|
||||
obj.expiresOn = new Date(<string>obj.expiresOn);
|
||||
}
|
||||
|
||||
return cacheObj;
|
||||
@@ -297,7 +293,7 @@ export default class TokenCache implements adal.TokenCache {
|
||||
// 4) Encrypt the JSON
|
||||
// 3) Write to the file
|
||||
return this.getOrCreateEncryptionParams()
|
||||
.then(encryptionParams => {
|
||||
.then(async encryptionParams => {
|
||||
try {
|
||||
let cacheJson = JSON.stringify(cache);
|
||||
|
||||
@@ -305,7 +301,7 @@ export default class TokenCache implements adal.TokenCache {
|
||||
let cacheCipher = cipher.update(cacheJson, 'utf8', 'hex');
|
||||
cacheCipher += cipher.final('hex');
|
||||
|
||||
fs.writeFileSync(self._cacheSerializationPath, cacheCipher, TokenCache.FsOptions);
|
||||
await fs.writeFile(self._cacheSerializationPath, cacheCipher, TokenCache.FsOptions);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as fs from 'fs';
|
||||
import { promises as fs } from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as constants from './constants';
|
||||
@@ -54,12 +54,12 @@ function pushDisposable(disposable: vscode.Disposable): void {
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
extensionContext = context;
|
||||
const apiWrapper = new ApiWrapper();
|
||||
let appContext = new AppContext(extensionContext, apiWrapper);
|
||||
|
||||
let storagePath = findOrMakeStoragePath();
|
||||
let storagePath = await findOrMakeStoragePath();
|
||||
if (!storagePath) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -82,12 +82,21 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
};
|
||||
}
|
||||
|
||||
async function exists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await fs.access(path);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the folder for storing the token caches
|
||||
function findOrMakeStoragePath() {
|
||||
async function findOrMakeStoragePath() {
|
||||
let storagePath = path.join(getDefaultLogLocation(), constants.extensionName);
|
||||
try {
|
||||
if (!fs.existsSync(storagePath)) {
|
||||
fs.mkdirSync(storagePath);
|
||||
if (!(await exists(storagePath))) {
|
||||
await fs.mkdir(storagePath);
|
||||
console.log('Initialized Azure account extension storage.');
|
||||
}
|
||||
}
|
||||
@@ -124,4 +133,3 @@ function registerCommands(appContext: AppContext, azureResourceTree: AzureResour
|
||||
|
||||
registerAzureResourceDatabaseCommands(appContext);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user