web - implement credentials provider and add API

This commit is contained in:
Benjamin Pasero
2019-08-15 13:13:58 +02:00
parent 2b22c0a0b2
commit 92dafb390c
12 changed files with 186 additions and 58 deletions

View File

@@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export interface ICredentialsProvider {
getPassword(service: string, account: string): Promise<string | null>;
setPassword(service: string, account: string, password: string): Promise<void>;
deletePassword(service: string, account: string): Promise<boolean>;
findPassword(service: string): Promise<string | null>;
}
export class BrowserCredentialsService implements ICredentialsService {
_serviceBrand!: ServiceIdentifier<any>;
private credentialsProvider: ICredentialsProvider;
constructor(@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService) {
if (environmentService.options && environmentService.options.credentialsProvider) {
this.credentialsProvider = environmentService.options.credentialsProvider;
} else {
this.credentialsProvider = new LocalStorageCredentialsProvider();
}
}
async getPassword(service: string, account: string): Promise<string | null> {
return this.credentialsProvider.getPassword(service, account);
}
async setPassword(service: string, account: string, password: string): Promise<void> {
return this.credentialsProvider.setPassword(service, account, password);
}
async deletePassword(service: string, account: string): Promise<boolean> {
return this.credentialsProvider.deletePassword(service, account);
}
async findPassword(service: string): Promise<string | null> {
return this.credentialsProvider.findPassword(service);
}
}
interface ICredential {
service: string;
account: string;
password: string;
}
class LocalStorageCredentialsProvider implements ICredentialsProvider {
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
private _credentials: ICredential[];
private get credentials(): ICredential[] {
if (!this._credentials) {
try {
const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY);
if (serializedCredentials) {
this._credentials = JSON.parse(serializedCredentials);
}
} catch (error) {
// ignore
}
if (!Array.isArray(this._credentials)) {
this._credentials = [];
}
}
return this._credentials;
}
private save(): void {
window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY, JSON.stringify(this.credentials));
}
async getPassword(service: string, account: string): Promise<string | null> {
return this.doGetPassword(service, account);
}
private async doGetPassword(service: string, account?: string): Promise<string | null> {
for (const credential of this.credentials) {
if (credential.service === service) {
if (typeof account !== 'string' || account === credential.account) {
return credential.password;
}
}
}
return null;
}
async setPassword(service: string, account: string, password: string): Promise<void> {
this.deletePassword(service, account);
this.credentials.push({ service, account, password });
this.save();
}
async deletePassword(service: string, account: string): Promise<boolean> {
let found = false;
this._credentials = this.credentials.filter(credential => {
if (credential.service === service && credential.account === account) {
found = true;
return false;
}
return true;
});
if (found) {
this.save();
}
return found;
}
async findPassword(service: string): Promise<string | null> {
return this.doGetPassword(service);
}
}
registerSingleton(ICredentialsService, BrowserCredentialsService, true);